2020.8.11 BRBを再解析(log2FCを計算するため)、それに合わせて再解析


print(Sys.Date())
[1] "2020-08-11"
print(sessionInfo(),locale=FALSE)
R version 4.0.1 (2020-06-06)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Red Hat Enterprise Linux

Matrix products: default
BLAS/LAPACK: /usr/local/intel2018_up1/compilers_and_libraries_2018.0.128/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so

attached base packages:
 [1] grid      stats4    parallel  stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] stringr_1.4.0                             hrbrthemes_0.8.0                          ggrepel_0.8.2                            
 [4] ggpubr_0.4.0.999                          gplots_3.0.4                              DESeq2_1.28.1                            
 [7] GGally_2.0.0                              vcd_1.4-7                                 BiocParallel_1.22.0                      
[10] Matrix_1.2-18                             SummarizedExperiment_1.18.2               DelayedArray_0.14.1                      
[13] matrixStats_0.56.0                        motifmatchr_1.10.0                        org.Mm.eg.db_3.11.4                      
[16] TxDb.Mmusculus.UCSC.mm10.knownGene_3.10.0 org.Hs.eg.db_3.11.4                       TxDb.Hsapiens.UCSC.hg19.knownGene_3.2.2  
[19] GenomicFeatures_1.40.1                    AnnotationDbi_1.50.3                      Biobase_2.48.0                           
[22] ChIPseeker_1.24.0                         clusterProfiler_3.16.0                    BSgenome.Mmusculus.UCSC.mm10_1.4.0       
[25] ggsignif_0.6.0                            chromVAR_1.10.0                           purrr_0.3.4                              
[28] RColorBrewer_1.1-2                        ggsci_2.9                                 readr_1.3.1                              
[31] tidyr_1.1.1                               dplyr_1.0.1                               ggplot2_3.3.2                            
[34] TFBSTools_1.26.0                          BSgenome_1.56.0                           rtracklayer_1.48.0                       
[37] Biostrings_2.56.0                         XVector_0.28.0                            GenomicRanges_1.40.0                     
[40] GenomeInfoDb_1.24.2                       IRanges_2.22.2                            S4Vectors_0.26.1                         
[43] BiocGenerics_0.34.0                      

loaded via a namespace (and not attached):
  [1] rappdirs_0.3.1              R.methodsS3_1.8.0           bit64_4.0.2                 knitr_1.29                  irlba_2.3.3                
  [6] R.utils_2.9.2               data.table_1.13.0           KEGGREST_1.28.0             RCurl_1.98-1.2              generics_0.0.2             
 [11] snow_0.4-3                  cowplot_1.0.0               lambda.r_1.2.4              RSQLite_2.2.0               europepmc_0.4              
 [16] bit_4.0.4                   enrichplot_1.8.1            xml2_1.3.2                  httpuv_1.5.4                isoband_0.2.2              
 [21] assertthat_0.2.1            DirichletMultinomial_1.30.0 viridis_0.5.1               xfun_0.16                   hms_0.5.3                  
 [26] evaluate_0.14               promises_1.1.1              fansi_0.4.1                 progress_1.2.2              caTools_1.18.0             
 [31] dbplyr_1.4.4                readxl_1.3.1                igraph_1.2.5                DBI_1.1.0                   geneplotter_1.66.0         
 [36] htmlwidgets_1.5.1           futile.logger_1.4.3         reshape_0.8.8               ellipsis_0.3.1              backports_1.1.8            
 [41] annotate_1.66.0             biomaRt_2.44.1              vctrs_0.3.2                 abind_1.4-5                 withr_2.2.0                
 [46] ggforce_0.3.2               triebeard_0.3.0             GenomicAlignments_1.24.0    prettyunits_1.1.1           DOSE_3.14.0                
 [51] lazyeval_0.2.2              seqLogo_1.54.3              crayon_1.3.4                genefilter_1.70.0           labeling_0.3               
 [56] pkgconfig_2.0.3             tweenr_1.0.1                nlme_3.1-148                rlang_0.4.7                 lifecycle_0.2.0            
 [61] miniUI_0.1.1.1              downloader_0.4              extrafontdb_1.0             BiocFileCache_1.12.1        cellranger_1.1.0           
 [66] polyclip_1.10-0             lmtest_0.9-37               urltools_1.7.3              carData_3.0-4               boot_1.3-25                
 [71] zoo_1.8-8                   base64enc_0.1-3             pheatmap_1.0.12             ggridges_0.5.2              png_0.1-7                  
 [76] viridisLite_0.3.0           bitops_1.0-6                R.oo_1.23.0                 KernSmooth_2.23-17          blob_1.2.1                 
 [81] qvalue_2.20.0               rstatix_0.6.0               gridGraphics_0.5-0          CNEr_1.24.0                 scales_1.1.1               
 [86] memoise_1.1.0               magrittr_1.5                plyr_1.8.6                  gdata_2.18.0                zlibbioc_1.34.0            
 [91] compiler_4.0.1              scatterpie_0.1.4            plotrix_3.7-8               Rsamtools_2.4.0             cli_2.0.2                  
 [96] formatR_1.7                 mgcv_1.8-31                 MASS_7.3-51.6               tidyselect_1.1.0            stringi_1.4.6              
[101] forcats_0.5.0               yaml_2.2.1                  GOSemSim_2.14.1             askpass_1.1                 locfit_1.5-9.4             
[106] fastmatch_1.1-0             tools_4.0.1                 rio_0.5.16                  rstudioapi_0.11             TFMPvalue_0.0.8            
[111] foreign_0.8-80              gridExtra_2.3               farver_2.0.3                ggraph_2.0.3                digest_0.6.25              
[116] rvcheck_0.1.8               BiocManager_1.30.10         FNN_1.1.3                   shiny_1.5.0                 pracma_2.2.9               
[121] Rcpp_1.0.5                  car_3.0-8                   broom_0.7.0                 later_1.1.0.1               gdtools_0.2.2              
[126] httr_1.4.2                  colorspace_1.4-1            XML_3.99-0.5                splines_4.0.1               uwot_0.1.8                 
[131] graphlayouts_0.7.0          ggplotify_0.0.5             systemfonts_0.2.3           plotly_4.9.2.1              xtable_1.8-4               
[136] jsonlite_1.7.0              futile.options_1.0.1        poweRlaw_0.70.6             tidygraph_1.2.0             R6_2.4.1                   
[141] pillar_1.4.6                htmltools_0.5.0             mime_0.9                    glue_1.4.1                  fastmap_1.0.1              
[146] DT_0.15                     fgsea_1.14.0                utf8_1.1.4                  lattice_0.20-41             tibble_3.0.3               
[151] curl_4.3                    gtools_3.8.2                Rttf2pt1_1.3.8              zip_2.1.0                   GO.db_3.11.4               
[156] openxlsx_4.1.5              openssl_1.4.2               survival_3.2-3              rmarkdown_2.3               munsell_0.5.0              
[161] DO.db_2.9                   GenomeInfoDbData_1.2.3      msigdbr_7.1.1               haven_2.3.1                 reshape2_1.4.4             
[166] gtable_0.3.0                extrafont_0.17             
#{r setup 0, include=FALSE} knitr::opts_chunk$set(echo = TRUE)

library(ggplot2)
library(dplyr)
library(tidyr)
library(purrr)
source("/home/guestA/n70275b/work/rscripts/geomNorm.R")

## ラベルあり
ggpoints <- function(x,...) 
  ggplot(x,...) + geom_point(stroke=1) +
  ggrepel::geom_text_repel(size=4) + theme_minimal() + mycolor

maxchrom <- 19 # 19: mouse, 22: human

mycolor <- ggsci::scale_color_aaas()

# PCA/UMAP
scalerows <- TRUE # gene-wise scaling (pattern is the matter?)
ntop <- 500 # number of top-n genes with high variance
seed <- 123 # set another number if UMAP looks not good
n_nei <- 6  # number of neighboring data points in UMAP #ここをどうしたらいい?


#----------------#

#cluster_num <- 4 

filepath_summary <- "/home/guestA/o70578a/akuwakado/kuwakado/ChILSeq2/Komatsu_3T3_EGFP_H3mm18_Dox_chIl_0111NOVAseq/TSS_count/ChILAll_TSS_pm5kb_withATAC/ChIL01100111_ATAC0049L1__3T3_EGFP18_Dox__TSS_pm5kb_20200624.count.txt"

# deftable 修正版
filepath_def <- "/home/guestA/o70578a/akuwakado/kuwakado/ChILSeq2/Komatsu_3T3_EGFP_H3mm18_Dox_chIl_0111NOVAseq/TSS_count/ChILAll_TSS_pm5kb_withATAC/deftable_multicov_ChIL01100111_20200501_3T3_EGFP18_UI_DoxMinus_H3p3K27acK4Kme327me3_withATAC.txt"



#--- サンプルの選択 ---#

folder_name <- "ChIL H3.3, H3K27ac, H3K4me3, H3K27me3, ATAC" #"ChIL_H3K27me3_H3K27me3"
#remove_sample=c("Doxminus_UI_ATAC_4","Doxplus_UI_ATAC_4","Doxminus_D48_ATAC_1","Doxminus_D48_ATAC_4","Doxplus_D48_ATAC_4") #このサンプルを削除(20190917) <ATACの場合>

#use <- quo(!(sample %in% remove_sample)) #このサンプルを削除(20190917)

#--- multiBamSummary の略 ---#
# データ保存用のpath
#csvfilepath <- basename(filepath_summary) %>% sub(".count.txt", "__", .)
csvfilepath <- basename(filepath_summary) %>% sub(".count.txt", "", .)  %>% sub("ChIL01100111_ATAC0049L1__3T3_EGFP18_Dox__", "", .)
print(csvfilepath)
[1] "TSS_pm5kb_20200624"

ensembleのデータの読み込み

filepath_BRBensemble <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Last_Rserver_200811/ensemble_list_useast.csv" #BRBの時のgene名リスト

ensemble <- readr::read_csv(filepath_BRBensemble) %>% mutate_if(is.double, as.integer)
Parsed with column specification:
cols(
  ens_gene = col_character(),
  ext_gene = col_character(),
  biotype = col_character(),
  chr = col_character()
)
annotate <- partial(right_join,ensemble,by="ens_gene") #2gunで使う

Select regions

UCSCの形式の場合 (20191016)

unite tables


# 20200617

def_list <- readr::read_tsv(filepath_def) %>% mutate(seq=factor(seq, c("ATAC","H3p3", "H3K27ac","H3K4me3","H3K27me3")))  %>% 
mutate(time1 = time, rep1=rep) %>% unite(time1,rep1,col="time_replicate")  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% mutate(type=factor(type,c("DoxPlus","DoxMinus"))) %>% mutate(rep=factor(rep, c("1", "2", "3", "4")))%>% mutate(time_replicate=factor(time_replicate,c("UI_1", "UI_2", "UI_3", "UI_4", "0h_1","0h_2","24h_1","24h_2","48h_1","48h_2","48h_3","48h_4")))
Parsed with column specification:
cols(
  file = col_character(),
  multicov_No = col_double(),
  sample = col_character(),
  group = col_character(),
  time = col_character(),
  type = col_character(),
  seq = col_character(),
  rep = col_double()
)
#def_list <- readr::read_tsv(filepath_def) %>% mutate(seq=factor(seq, c("H3p3", "H3K27ac","H3K4me3","H3K27me3")))  %>% 
#mutate(time1 = time, rep1=rep) %>% unite(time1,rep1,col="time_replicate")  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% mutate(type=factor(type,c("DoxPlus","DoxMinus"))) %>% mutate(rep=factor(rep, c("1", "2")))%>% mutate(time_replicate=factor(time_replicate,c("UI_1", "UI_2", "0h_1","0h_2","24h_1","24h_2","48h_1","48h_2")))


# add 20200617
groups <- c(
  "ATAC_UI_DoxMinus","ATAC_UI_DoxPlus",
  "ATAC_48h_DoxMinus","ATAC_48h_DoxPlus",
  
  "H3p3_UI_DoxMinus","H3p3_UI_DoxPlus",
  "H3p3_0h_DoxMinus","H3p3_0h_DoxPlus",
  "H3p3_24h_DoxMinus","H3p3_24h_DoxPlus",
  "H3p3_48h_DoxMinus","H3p3_48h_DoxPlus",
  
  "H3K27ac_UI_DoxMinus","H3K27ac_UI_DoxPlus",
  "H3K27ac_0h_DoxMinus","H3K27ac_0h_DoxPlus",
  "H3K27ac_24h_DoxMinus","H3K27ac_24h_DoxPlus",
  "H3K27ac_48h_DoxMinus","H3K27ac_48h_DoxPlus",
  
  "H3K4me3_UI_DoxMinus","H3K4me3_UI_DoxPlus",
  "H3K4me3_0h_DoxMinus","H3K4me3_0h_DoxPlus",
  "H3K4me3_24h_DoxMinus","H3K4me3_24h_DoxPlus",
  "H3K4me3_48h_DoxMinus","H3K4me3_48h_DoxPlus",
  
  "H3K27me3_UI_DoxMinus","H3K27me3_UI_DoxPlus",
  "H3K27me3_0h_DoxMinus","H3K27me3_0h_DoxPlus",
  "H3K27me3_24h_DoxMinus","H3K27me3_24h_DoxPlus",
  "H3K27me3_48h_DoxMinus","H3K27me3_48h_DoxPlus")

group_H3p3 <- c(
  "H3p3_UI_DoxMinus","H3p3_UI_DoxPlus",
  "H3p3_0h_DoxMinus","H3p3_0h_DoxPlus",
  "H3p3_24h_DoxMinus","H3p3_24h_DoxPlus",
  "H3p3_48h_DoxMinus","H3p3_48h_DoxPlus")

group_ATAC <- c(
  "ATAC_UI_DoxMinus","ATAC_UI_DoxPlus",
  "ATAC_48h_DoxMinus","ATAC_48h_DoxPlus")


samples <- c(
  "ATAC_UI_DoxMinus_1","ATAC_UI_DoxMinus_2","ATAC_UI_DoxMinus_3","ATAC_UI_DoxMinus_4",
  "ATAC_UI_DoxPlus_1","ATAC_UI_DoxPlus_2","ATAC_UI_DoxPlus_3","ATAC_UI_DoxPlus_4",
  "ATAC_48h_DoxMinus_1","ATAC_48h_DoxMinus_2","ATAC_48h_DoxMinus_3","ATAC_48h_DoxMinus_4",
  "ATAC_48h_DoxPlus_1","ATAC_48h_DoxPlus_2","ATAC_48h_DoxPlus_3","ATAC_48h_DoxPlus_4",
  
  "H3p3_UI_DoxMinus_1","H3p3_UI_DoxMinus_2","H3p3_UI_DoxPlus_1","H3p3_UI_DoxPlus_2",
  "H3p3_0h_DoxMinus_1","H3p3_0h_DoxMinus_2","H3p3_0h_DoxPlus_1","H3p3_0h_DoxPlus_2",
  "H3p3_24h_DoxMinus_1","H3p3_24h_DoxMinus_2","H3p3_24h_DoxPlus_1","H3p3_24h_DoxPlus_2",
  "H3p3_48h_DoxMinus_1","H3p3_48h_DoxMinus_2","H3p3_48h_DoxPlus_1","H3p3_48h_DoxPlus_2",
  
  "H3K27ac_UI_DoxMinus_1","H3K27ac_UI_DoxMinus_2","H3K27ac_UI_DoxPlus_1","H3K27ac_UI_DoxPlus_2",
  "H3K27ac_0h_DoxMinus_1","H3K27ac_0h_DoxMinus_2","H3K27ac_0h_DoxPlus_1","H3K27ac_0h_DoxPlus_2",
  "H3K27ac_24h_DoxMinus_1","H3K27ac_24h_DoxMinus_2","H3K27ac_24h_DoxPlus_1","H3K27ac_24h_DoxPlus_2",
  "H3K27ac_48h_DoxMinus_1","H3K27ac_48h_DoxMinus_2","H3K27ac_48h_DoxPlus_1","H3K27ac_48h_DoxPlus_2",
  
  "H3K4me3_UI_DoxMinus_1","H3K4me3_UI_DoxMinus_2","H3K4me3_UI_DoxPlus_1","H3K4me3_UI_DoxPlus_2",
  "H3K4me3_0h_DoxMinus_1","H3K4me3_0h_DoxMinus_2","H3K4me3_0h_DoxPlus_1","H3K4me3_0h_DoxPlus_2",
  "H3K4me3_24h_DoxMinus_1","H3K4me3_24h_DoxMinus_2","H3K4me3_24h_DoxPlus_1","H3K4me3_24h_DoxPlus_2",
  "H3K4me3_48h_DoxMinus_1","H3K4me3_48h_DoxMinus_2","H3K4me3_48h_DoxPlus_1","H3K4me3_48h_DoxPlus_2",
  
  "H3K27me3_UI_DoxMinus_1","H3K27me3_UI_DoxMinus_2","H3K27me3_UI_DoxPlus_1","H3K27me3_UI_DoxPlus_2",
  "H3K27me3_0h_DoxMinus_1","H3K27me3_0h_DoxMinus_2","H3K27me3_0h_DoxPlus_1","H3K27me3_0h_DoxPlus_2",
  "H3K27me3_24h_DoxMinus_1","H3K27me3_24h_DoxMinus_2","H3K27me3_24h_DoxPlus_1","H3K27me3_24h_DoxPlus_2",
  "H3K27me3_48h_DoxMinus_1","H3K27me3_48h_DoxMinus_2","H3K27me3_48h_DoxPlus_1","H3K27me3_48h_DoxPlus_2")

samples_ATAC <- c(
  "ATAC_UI_DoxMinus_1","ATAC_UI_DoxMinus_2","ATAC_UI_DoxMinus_3","ATAC_UI_DoxMinus_4",
  "ATAC_UI_DoxPlus_1","ATAC_UI_DoxPlus_2","ATAC_UI_DoxPlus_3","ATAC_UI_DoxPlus_4",
  "ATAC_48h_DoxMinus_1","ATAC_48h_DoxMinus_2","ATAC_48h_DoxMinus_3","ATAC_48h_DoxMinus_4",
  "ATAC_48h_DoxPlus_1","ATAC_48h_DoxPlus_2","ATAC_48h_DoxPlus_3","ATAC_48h_DoxPlus_4")

samples_H3p3 <- c(
  "H3p3_UI_DoxMinus_1","H3p3_UI_DoxMinus_2","H3p3_UI_DoxPlus_1","H3p3_UI_DoxPlus_2",
  "H3p3_0h_DoxMinus_1","H3p3_0h_DoxMinus_2","H3p3_0h_DoxPlus_1","H3p3_0h_DoxPlus_2",
  "H3p3_24h_DoxMinus_1","H3p3_24h_DoxMinus_2","H3p3_24h_DoxPlus_1","H3p3_24h_DoxPlus_2",
  "H3p3_48h_DoxMinus_1","H3p3_48h_DoxMinus_2","H3p3_48h_DoxPlus_1","H3p3_48h_DoxPlus_2")

samples_H3K27ac <- c(
  "H3K27ac_UI_DoxMinus_1","H3K27ac_UI_DoxMinus_2","H3K27ac_UI_DoxPlus_1","H3K27ac_UI_DoxPlus_2",
  "H3K27ac_0h_DoxMinus_1","H3K27ac_0h_DoxMinus_2","H3K27ac_0h_DoxPlus_1","H3K27ac_0h_DoxPlus_2",
  "H3K27ac_24h_DoxMinus_1","H3K27ac_24h_DoxMinus_2","H3K27ac_24h_DoxPlus_1","H3K27ac_24h_DoxPlus_2",
  "H3K27ac_48h_DoxMinus_1","H3K27ac_48h_DoxMinus_2","H3K27ac_48h_DoxPlus_1","H3K27ac_48h_DoxPlus_2")

samples_H3K4me3 <- c(
  "H3K4me3_UI_DoxMinus_1","H3K4me3_UI_DoxMinus_2","H3K4me3_UI_DoxPlus_1","H3K4me3_UI_DoxPlus_2",
  "H3K4me3_0h_DoxMinus_1","H3K4me3_0h_DoxMinus_2","H3K4me3_0h_DoxPlus_1","H3K4me3_0h_DoxPlus_2",
  "H3K4me3_24h_DoxMinus_1","H3K4me3_24h_DoxMinus_2","H3K4me3_24h_DoxPlus_1","H3K4me3_24h_DoxPlus_2",
  "H3K4me3_48h_DoxMinus_1","H3K4me3_48h_DoxMinus_2","H3K4me3_48h_DoxPlus_1","H3K4me3_48h_DoxPlus_2")

samples_H3K27me3 <- c(
  "H3K27me3_UI_DoxMinus_1","H3K27me3_UI_DoxMinus_2","H3K27me3_UI_DoxPlus_1","H3K27me3_UI_DoxPlus_2",
  "H3K27me3_0h_DoxMinus_1","H3K27me3_0h_DoxMinus_2","H3K27me3_0h_DoxPlus_1","H3K27me3_0h_DoxPlus_2",
  "H3K27me3_24h_DoxMinus_1","H3K27me3_24h_DoxMinus_2","H3K27me3_24h_DoxPlus_1","H3K27me3_24h_DoxPlus_2",
  "H3K27me3_48h_DoxMinus_1","H3K27me3_48h_DoxMinus_2","H3K27me3_48h_DoxPlus_1","H3K27me3_48h_DoxPlus_2")






f_sample <- function(x) x %>% mutate(sample=factor(sample, samples))
f_group <- function(x) x %>% mutate(group=factor(group, groups))

# filter(sample!="Doxminus_D48_ATAC_1") => filter((sample!="Doxminus_D48_ATAC_1")&(rep!="lot4")) (2020 0114修正)

#def_list <- def_list %>% f_sample %>% f_group

####
def_list_select <- def_list
def_list_select_0 <- def_list  %>% dplyr::select(-"file",-"multicov_No") %>% filter(seq=="ATAC")
def_list_select_1 <- def_list  %>% dplyr::select(-"file",-"multicov_No") %>% filter(seq=="H3p3")
def_list_select_2 <- def_list  %>% dplyr::select(-"file",-"multicov_No") %>% filter(seq=="H3K27ac")
def_list_select_3 <- def_list  %>% dplyr::select(-"file",-"multicov_No") %>% filter(seq=="H3K4me3")
def_list_select_4 <- def_list  %>% dplyr::select(-"file",-"multicov_No") %>% filter(seq=="H3K27me3")

#def_list_select <- def_list %>% filter(!!use) #使わないサンプルを削除(20190917)

#%>% 
#mutate(time1 = time, rep1=rep) %>% unite(time1,rep1,col="time_replicate") %>% #mutate(time_replicate=factor(time_replicate,c("UI_1","UI_2","D1","D48_lot2")))

# narrowpeak の場合 (型を指定) 200612modif 200615modif
#narrow_colnames <- c("chr","start","end","name","score","strand","singnalValue","pValue","qValue","peak","chr0","start0","end0")

merge_colnames <- c("chr","TSSstart","TSSend","ens_gene","score","strand","TSS","Start","End")

matome0 <- readr::read_tsv(filepath_summary, col_names = c(merge_colnames, def_list$sample))  %>% mutate_if(names(.) %in% c("start","end","TSS","Start","End",def_list$sample), as.integer)
Parsed with column specification:
cols(
  .default = col_double(),
  chr = col_character(),
  ens_gene = col_character(),
  score = col_character(),
  strand = col_character()
)
See spec(...) for full column specifications.
matome0 %>% dplyr::select("chr","TSSstart","TSSend","ens_gene") %>% unique() # # A tibble: 105,166 x 4

#matome0 %>% group_by(chr,ens_gene,strand,Start,End) %>% unique() # # A tibble: 105,166 x 4

#matome <- matome0 %>% group_by(chr,start,end,Name) %>% dplyr::top_n(1, singnalValue)  %>% dplyr::top_n(1, peak) %>% dplyr::ungroup()

#matome  <- matome0 %>% filter_at(def_list$sample,any_vars(. > 0))

matome1 <- matome0 %>% gather("sample", "count", -("chr":"End")) %>% filter(sample %in% def_list_select$sample) %>% left_join(def_list_select, .,by = "sample")

# %>% dplyr::select(-"score",-"strand",-"singnalValue",-"pValue",-"qValue",-"peak")

#---- 確認 ----#
matome0 %>% nrow()
[1] 133122
filename <- gsub(".txt","__count.csv",basename(filepath_summary))  #geneにつき複数領域
matome0 %>% readr::write_csv(filename)
print(filename)
[1] "ChIL01100111_ATAC0049L1__3T3_EGFP18_Dox__TSS_pm5kb_20200624.count__count.csv"
#filename <- gsub(".txt","__select_nameonly.csv",basename(filepath_def))
#matome %>% dplyr::select("chr","start","end","name") %>% readr::write_csv(filename)
#print(filename)

#matome %>% dplyr::select("chr","start","end","name","score","Name","strand","singnalValue","pValue","qValue","peak","chr0","start0","end0") %>% readr::write_csv(filename)
#print(filename)

#matome00 <- matome0 %>% group_by(chr,start,end,Name) %>% summarise(max_score=max(score), paste(Name, collapse="")) #dplyr::top_n(score,1)
  
#matome <- matome0 %>% filter(name %in% matome00$name)

#matome %>% mutate(name1=name) %>% filter(grepl("[a-u]$",name)) %>% mutate(Name=gsub("[a-u]$","",name))


#mat_select <- matome %>% dplyr::select(chr,start,end,name,Name) 
#annotate_bed <- partial(right_join,mat_select,by="ens_gene") #2gunで使う
#matome1_number <- matome1 %>% mutate(position = row_number())
#matome1_plus <- matome1_number %>% filter(strand=="+")
#matome1_minus <- matome1_number %>% filter(strand=="-")

matome0_number <- matome0 %>% mutate(position = row_number())
nrow(matome0_number)
[1] 133122
matome0_plus <- matome0_number %>% filter(strand=="+")
matome0_minus <- matome0_number %>% filter(strand=="-")

matome0_plus_o <- matome0_plus %>% group_by(chr,ens_gene) %>% dplyr::top_n(-1,TSS) #低
matome0_minus_o <- matome0_minus %>% group_by(chr,ens_gene) %>% dplyr::top_n(1,TSS) #高

matome0_o <- dplyr::bind_rows(matome0_plus_o, matome0_minus_o) %>% arrange(position)
nrow(matome0_o)
[1] 55487
##----- 確認 ---------##
colnames(matome0_o) 
 [1] "chr"                     "TSSstart"                "TSSend"                  "ens_gene"                "score"                  
 [6] "strand"                  "TSS"                     "Start"                   "End"                     "H3p3_UI_DoxMinus_1"     
[11] "H3p3_UI_DoxMinus_2"      "H3p3_UI_DoxPlus_1"       "H3p3_UI_DoxPlus_2"       "H3p3_0h_DoxMinus_1"      "H3p3_0h_DoxMinus_2"     
[16] "H3p3_0h_DoxPlus_1"       "H3p3_0h_DoxPlus_2"       "H3p3_24h_DoxMinus_1"     "H3p3_24h_DoxMinus_2"     "H3p3_24h_DoxPlus_1"     
[21] "H3p3_24h_DoxPlus_2"      "H3p3_48h_DoxMinus_1"     "H3p3_48h_DoxMinus_2"     "H3p3_48h_DoxPlus_1"      "H3p3_48h_DoxPlus_2"     
[26] "H3K27ac_UI_DoxMinus_1"   "H3K27ac_UI_DoxMinus_2"   "H3K27ac_UI_DoxPlus_1"    "H3K27ac_UI_DoxPlus_2"    "H3K27ac_0h_DoxMinus_1"  
[31] "H3K27ac_0h_DoxMinus_2"   "H3K27ac_0h_DoxPlus_1"    "H3K27ac_0h_DoxPlus_2"    "H3K27ac_24h_DoxMinus_1"  "H3K27ac_24h_DoxMinus_2" 
[36] "H3K27ac_24h_DoxPlus_1"   "H3K27ac_24h_DoxPlus_2"   "H3K27ac_48h_DoxMinus_1"  "H3K27ac_48h_DoxMinus_2"  "H3K27ac_48h_DoxPlus_1"  
[41] "H3K27ac_48h_DoxPlus_2"   "H3K4me3_UI_DoxMinus_1"   "H3K4me3_UI_DoxMinus_2"   "H3K4me3_UI_DoxPlus_1"    "H3K4me3_UI_DoxPlus_2"   
[46] "H3K4me3_0h_DoxMinus_1"   "H3K4me3_0h_DoxMinus_2"   "H3K4me3_0h_DoxPlus_1"    "H3K4me3_0h_DoxPlus_2"    "H3K4me3_24h_DoxMinus_1" 
[51] "H3K4me3_24h_DoxMinus_2"  "H3K4me3_24h_DoxPlus_1"   "H3K4me3_24h_DoxPlus_2"   "H3K4me3_48h_DoxMinus_1"  "H3K4me3_48h_DoxMinus_2" 
[56] "H3K4me3_48h_DoxPlus_1"   "H3K4me3_48h_DoxPlus_2"   "H3K27me3_UI_DoxMinus_1"  "H3K27me3_UI_DoxMinus_2"  "H3K27me3_UI_DoxPlus_1"  
[61] "H3K27me3_UI_DoxPlus_2"   "H3K27me3_0h_DoxMinus_1"  "H3K27me3_0h_DoxMinus_2"  "H3K27me3_0h_DoxPlus_1"   "H3K27me3_0h_DoxPlus_2"  
[66] "H3K27me3_24h_DoxMinus_1" "H3K27me3_24h_DoxMinus_2" "H3K27me3_24h_DoxPlus_1"  "H3K27me3_24h_DoxPlus_2"  "H3K27me3_48h_DoxMinus_1"
[71] "H3K27me3_48h_DoxMinus_2" "H3K27me3_48h_DoxPlus_1"  "H3K27me3_48h_DoxPlus_2"  "ATAC_UI_DoxMinus_1"      "ATAC_UI_DoxMinus_2"     
[76] "ATAC_UI_DoxMinus_3"      "ATAC_UI_DoxMinus_4"      "ATAC_UI_DoxPlus_1"       "ATAC_UI_DoxPlus_2"       "ATAC_UI_DoxPlus_3"      
[81] "ATAC_UI_DoxPlus_4"       "ATAC_48h_DoxMinus_1"     "ATAC_48h_DoxMinus_2"     "ATAC_48h_DoxMinus_3"     "ATAC_48h_DoxMinus_4"    
[86] "ATAC_48h_DoxPlus_1"      "ATAC_48h_DoxPlus_2"      "ATAC_48h_DoxPlus_3"      "ATAC_48h_DoxPlus_4"      "position"               
nrow(matome0_o)
[1] 55487
filename <- gsub(".txt","__count_firstTSS.csv",basename(filepath_summary)) #geneにつき1領域
matome0_o %>% readr::write_csv(filename)
print(filename)
[1] "ChIL01100111_ATAC0049L1__3T3_EGFP18_Dox__TSS_pm5kb_20200624.count__count_firstTSS.csv"
##--------------------##

#matome0_plus %>% filter(ens_gene =="ENSMUSG00000000037") %>% dplyr::select(TSSstart,position)
#matome0_plus_o %>% filter(ens_gene =="ENSMUSG00000000037") %>% dplyr::select(TSSstart,position)

#%>% group_by(chr,TSSstart,TSSend,ens_gene,score,strand,TSS,Start,End,seq) 

#matome1_number %>% filter(!(strand=="+"|strand=="-"))
matome0_s <- matome0_o %>%  dplyr::select(chr,ens_gene,TSSstart,TSSend,score,strand,TSS,Start,End,position,all_of(samples)) %>% filter(chr!="chrM")
nrow(matome0_s)
[1] 55450
#matome0_s <- matome0_o %>% filter(ens_gene %in% FC_rank_all_BRBlist$ens_gene) %>% dplyr::select(chr,ens_gene,TSSstart,TSSend,score,strand,TSS,Start,End,position,all_of(samples))
nrow(matome0_s)
[1] 55450
#matome0_s1 <- matome0_s %>% left_join(FC_rank_all_BRBlist %>% dplyr::select(ens_gene,log2FoldChange,Rank))

matome5 <- matome0_s %>% dplyr::select(chr,ens_gene,position,all_of(samples)) %>% ungroup()


##----- 確認 ---------##
colnames(matome0_s) 
 [1] "chr"                     "ens_gene"                "TSSstart"                "TSSend"                  "score"                  
 [6] "strand"                  "TSS"                     "Start"                   "End"                     "position"               
[11] "ATAC_UI_DoxMinus_1"      "ATAC_UI_DoxMinus_2"      "ATAC_UI_DoxMinus_3"      "ATAC_UI_DoxMinus_4"      "ATAC_UI_DoxPlus_1"      
[16] "ATAC_UI_DoxPlus_2"       "ATAC_UI_DoxPlus_3"       "ATAC_UI_DoxPlus_4"       "ATAC_48h_DoxMinus_1"     "ATAC_48h_DoxMinus_2"    
[21] "ATAC_48h_DoxMinus_3"     "ATAC_48h_DoxMinus_4"     "ATAC_48h_DoxPlus_1"      "ATAC_48h_DoxPlus_2"      "ATAC_48h_DoxPlus_3"     
[26] "ATAC_48h_DoxPlus_4"      "H3p3_UI_DoxMinus_1"      "H3p3_UI_DoxMinus_2"      "H3p3_UI_DoxPlus_1"       "H3p3_UI_DoxPlus_2"      
[31] "H3p3_0h_DoxMinus_1"      "H3p3_0h_DoxMinus_2"      "H3p3_0h_DoxPlus_1"       "H3p3_0h_DoxPlus_2"       "H3p3_24h_DoxMinus_1"    
[36] "H3p3_24h_DoxMinus_2"     "H3p3_24h_DoxPlus_1"      "H3p3_24h_DoxPlus_2"      "H3p3_48h_DoxMinus_1"     "H3p3_48h_DoxMinus_2"    
[41] "H3p3_48h_DoxPlus_1"      "H3p3_48h_DoxPlus_2"      "H3K27ac_UI_DoxMinus_1"   "H3K27ac_UI_DoxMinus_2"   "H3K27ac_UI_DoxPlus_1"   
[46] "H3K27ac_UI_DoxPlus_2"    "H3K27ac_0h_DoxMinus_1"   "H3K27ac_0h_DoxMinus_2"   "H3K27ac_0h_DoxPlus_1"    "H3K27ac_0h_DoxPlus_2"   
[51] "H3K27ac_24h_DoxMinus_1"  "H3K27ac_24h_DoxMinus_2"  "H3K27ac_24h_DoxPlus_1"   "H3K27ac_24h_DoxPlus_2"   "H3K27ac_48h_DoxMinus_1" 
[56] "H3K27ac_48h_DoxMinus_2"  "H3K27ac_48h_DoxPlus_1"   "H3K27ac_48h_DoxPlus_2"   "H3K4me3_UI_DoxMinus_1"   "H3K4me3_UI_DoxMinus_2"  
[61] "H3K4me3_UI_DoxPlus_1"    "H3K4me3_UI_DoxPlus_2"    "H3K4me3_0h_DoxMinus_1"   "H3K4me3_0h_DoxMinus_2"   "H3K4me3_0h_DoxPlus_1"   
[66] "H3K4me3_0h_DoxPlus_2"    "H3K4me3_24h_DoxMinus_1"  "H3K4me3_24h_DoxMinus_2"  "H3K4me3_24h_DoxPlus_1"   "H3K4me3_24h_DoxPlus_2"  
[71] "H3K4me3_48h_DoxMinus_1"  "H3K4me3_48h_DoxMinus_2"  "H3K4me3_48h_DoxPlus_1"   "H3K4me3_48h_DoxPlus_2"   "H3K27me3_UI_DoxMinus_1" 
[76] "H3K27me3_UI_DoxMinus_2"  "H3K27me3_UI_DoxPlus_1"   "H3K27me3_UI_DoxPlus_2"   "H3K27me3_0h_DoxMinus_1"  "H3K27me3_0h_DoxMinus_2" 
[81] "H3K27me3_0h_DoxPlus_1"   "H3K27me3_0h_DoxPlus_2"   "H3K27me3_24h_DoxMinus_1" "H3K27me3_24h_DoxMinus_2" "H3K27me3_24h_DoxPlus_1" 
[86] "H3K27me3_24h_DoxPlus_2"  "H3K27me3_48h_DoxMinus_1" "H3K27me3_48h_DoxMinus_2" "H3K27me3_48h_DoxPlus_1"  "H3K27me3_48h_DoxPlus_2" 
nrow(matome0_s)
[1] 55450
filename <- gsub(".txt","__count_firstTSS_select.csv",basename(filepath_summary))  #geneにつき1領域、かつBRBでnormalized countがあるもの 
matome0_s %>% readr::write_csv(filename)
print(filename)
[1] "ChIL01100111_ATAC0049L1__3T3_EGFP18_Dox__TSS_pm5kb_20200624.count__count_firstTSS_select.csv"
##--------------------##

annotate_TSS <- partial(right_join,dplyr::select(matome0_s,chr,ens_gene,TSSstart,TSSend,score,strand,TSS,Start,End,position),by="ens_gene") #2gunで使う

normalized count

separate matrix


nrow(matome5)
[1] 55450
colnames(matome5)
 [1] "chr"                     "ens_gene"                "position"                "ATAC_UI_DoxMinus_1"      "ATAC_UI_DoxMinus_2"     
 [6] "ATAC_UI_DoxMinus_3"      "ATAC_UI_DoxMinus_4"      "ATAC_UI_DoxPlus_1"       "ATAC_UI_DoxPlus_2"       "ATAC_UI_DoxPlus_3"      
[11] "ATAC_UI_DoxPlus_4"       "ATAC_48h_DoxMinus_1"     "ATAC_48h_DoxMinus_2"     "ATAC_48h_DoxMinus_3"     "ATAC_48h_DoxMinus_4"    
[16] "ATAC_48h_DoxPlus_1"      "ATAC_48h_DoxPlus_2"      "ATAC_48h_DoxPlus_3"      "ATAC_48h_DoxPlus_4"      "H3p3_UI_DoxMinus_1"     
[21] "H3p3_UI_DoxMinus_2"      "H3p3_UI_DoxPlus_1"       "H3p3_UI_DoxPlus_2"       "H3p3_0h_DoxMinus_1"      "H3p3_0h_DoxMinus_2"     
[26] "H3p3_0h_DoxPlus_1"       "H3p3_0h_DoxPlus_2"       "H3p3_24h_DoxMinus_1"     "H3p3_24h_DoxMinus_2"     "H3p3_24h_DoxPlus_1"     
[31] "H3p3_24h_DoxPlus_2"      "H3p3_48h_DoxMinus_1"     "H3p3_48h_DoxMinus_2"     "H3p3_48h_DoxPlus_1"      "H3p3_48h_DoxPlus_2"     
[36] "H3K27ac_UI_DoxMinus_1"   "H3K27ac_UI_DoxMinus_2"   "H3K27ac_UI_DoxPlus_1"    "H3K27ac_UI_DoxPlus_2"    "H3K27ac_0h_DoxMinus_1"  
[41] "H3K27ac_0h_DoxMinus_2"   "H3K27ac_0h_DoxPlus_1"    "H3K27ac_0h_DoxPlus_2"    "H3K27ac_24h_DoxMinus_1"  "H3K27ac_24h_DoxMinus_2" 
[46] "H3K27ac_24h_DoxPlus_1"   "H3K27ac_24h_DoxPlus_2"   "H3K27ac_48h_DoxMinus_1"  "H3K27ac_48h_DoxMinus_2"  "H3K27ac_48h_DoxPlus_1"  
[51] "H3K27ac_48h_DoxPlus_2"   "H3K4me3_UI_DoxMinus_1"   "H3K4me3_UI_DoxMinus_2"   "H3K4me3_UI_DoxPlus_1"    "H3K4me3_UI_DoxPlus_2"   
[56] "H3K4me3_0h_DoxMinus_1"   "H3K4me3_0h_DoxMinus_2"   "H3K4me3_0h_DoxPlus_1"    "H3K4me3_0h_DoxPlus_2"    "H3K4me3_24h_DoxMinus_1" 
[61] "H3K4me3_24h_DoxMinus_2"  "H3K4me3_24h_DoxPlus_1"   "H3K4me3_24h_DoxPlus_2"   "H3K4me3_48h_DoxMinus_1"  "H3K4me3_48h_DoxMinus_2" 
[66] "H3K4me3_48h_DoxPlus_1"   "H3K4me3_48h_DoxPlus_2"   "H3K27me3_UI_DoxMinus_1"  "H3K27me3_UI_DoxMinus_2"  "H3K27me3_UI_DoxPlus_1"  
[71] "H3K27me3_UI_DoxPlus_2"   "H3K27me3_0h_DoxMinus_1"  "H3K27me3_0h_DoxMinus_2"  "H3K27me3_0h_DoxPlus_1"   "H3K27me3_0h_DoxPlus_2"  
[76] "H3K27me3_24h_DoxMinus_1" "H3K27me3_24h_DoxMinus_2" "H3K27me3_24h_DoxPlus_1"  "H3K27me3_24h_DoxPlus_2"  "H3K27me3_48h_DoxMinus_1"
[81] "H3K27me3_48h_DoxMinus_2" "H3K27me3_48h_DoxPlus_1"  "H3K27me3_48h_DoxPlus_2" 
X <- matome5 %>% dplyr::select(all_of(samples)) %>% as.matrix
rownames(X) <- matome5$ens_gene

###--- DESeq2によりnormalized count (必要なサンプルのみ) ---###
model<- ~group
dds_ATAC <- DESeq2::DESeqDataSetFromMatrix(X[,def_list_select_0$sample],def_list_select_0,model) #ATAC
some variables in design formula are characters, converting to factors
dds_H3p3 <- DESeq2::DESeqDataSetFromMatrix(X[,def_list_select_1$sample],def_list_select_1,model) #H3p3
some variables in design formula are characters, converting to factors
dds_H3K27ac <- DESeq2::DESeqDataSetFromMatrix(X[,def_list_select_2$sample],def_list_select_2,model) #H3K27ac
some variables in design formula are characters, converting to factors
dds_H3K4me3 <- DESeq2::DESeqDataSetFromMatrix(X[,def_list_select_3$sample],def_list_select_3,model) #H3K4me3
some variables in design formula are characters, converting to factors
dds_H3K27me3 <- DESeq2::DESeqDataSetFromMatrix(X[,def_list_select_4$sample],def_list_select_4,model) #H3K27me3
some variables in design formula are characters, converting to factors

Fit model

#model_2gun <- ~group
#dds_2gun <- DESeq2::DESeqDataSetFromMatrix(X[,def_list_select$sample],def_list_select,model_2gun)
dds_ATAC <- DESeq2::DESeq(dds_ATAC)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
dds_H3p3 <- DESeq2::DESeq(dds_H3p3)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
dds_H3K27ac <- DESeq2::DESeq(dds_H3K27ac)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
-- note: fitType='parametric', but the dispersion trend was not well captured by the
   function: y = a/x + b, and a local regression fit was automatically substituted.
   specify fitType='local' or 'mean' to avoid this message next time.
final dispersion estimates
fitting model and testing
dds_H3K4me3 <- DESeq2::DESeq(dds_H3K4me3)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
-- note: fitType='parametric', but the dispersion trend was not well captured by the
   function: y = a/x + b, and a local regression fit was automatically substituted.
   specify fitType='local' or 'mean' to avoid this message next time.
final dispersion estimates
fitting model and testing
dds_H3K27me3 <- DESeq2::DESeq(dds_H3K27me3)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
-- note: fitType='parametric', but the dispersion trend was not well captured by the
   function: y = a/x + b, and a local regression fit was automatically substituted.
   specify fitType='local' or 'mean' to avoid this message next time.
final dispersion estimates
fitting model and testing
#keep <- rowSums(counts(dds)) >= 10 #low countは削る方法
#dds <- dds[keep,] #low countは削る方法

Diagnostics plot

DESeq2::sizeFactors(dds_ATAC) %>%
  {tibble(sample=names(.),sizeFactor=.)} %>%
  ggplot(aes(sample,sizeFactor)) + theme_minimal() +
  geom_bar(stat="identity") + coord_flip()

DESeq2::plotDispEsts(dds_ATAC)


DESeq2::sizeFactors(dds_H3p3) %>%
  {tibble(sample=names(.),sizeFactor=.)} %>%
  ggplot(aes(sample,sizeFactor)) + theme_minimal() +
  geom_bar(stat="identity") + coord_flip()

DESeq2::plotDispEsts(dds_H3p3)


DESeq2::sizeFactors(dds_H3K27ac) %>%
  {tibble(sample=names(.),sizeFactor=.)} %>%
  ggplot(aes(sample,sizeFactor)) + theme_minimal() +
  geom_bar(stat="identity") + coord_flip()

DESeq2::plotDispEsts(dds_H3K27ac)


DESeq2::sizeFactors(dds_H3K4me3) %>%
  {tibble(sample=names(.),sizeFactor=.)} %>%
  ggplot(aes(sample,sizeFactor)) + theme_minimal() +
  geom_bar(stat="identity") + coord_flip()

DESeq2::plotDispEsts(dds_H3K4me3)


DESeq2::sizeFactors(dds_H3K27me3) %>%
  {tibble(sample=names(.),sizeFactor=.)} %>%
  ggplot(aes(sample,sizeFactor)) + theme_minimal() +
  geom_bar(stat="identity") + coord_flip()

DESeq2::plotDispEsts(dds_H3K27me3)

normalized count listを書き出し


# ATAC
dds_ATAC <- DESeq2::estimateSizeFactors(dds_ATAC)
norm_ATAC <- DESeq2::counts(dds_ATAC,normalized=TRUE) #DEGを取った後のクラスタリングに使う。

normalizedcount_ATAC <- as.data.frame(norm_ATAC) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_0$sample))
filename <- paste(csvfilepath,"_normcount_ATAC.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_ATAC.csv"
readr::write_csv(normalizedcount_ATAC, filename)
nrow(normalizedcount_ATAC)
[1] 55450
ncol(normalizedcount_ATAC)
[1] 17
norm_gene_ATAC <- normalizedcount_ATAC %>% inner_join(ensemble) %>% dplyr::select("ens_gene","ext_gene", "biotype","chr", all_of(def_list_select_0$sample))
Joining, by = "ens_gene"
filename <- paste(csvfilepath,"_normcount_ATAC_genename.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_ATAC_genename.csv"
readr::write_csv(norm_gene_ATAC, filename)
nrow(norm_gene_ATAC)
[1] 55197
ncol(norm_gene_ATAC)
[1] 20
# H3p3
dds_H3p3 <- DESeq2::estimateSizeFactors(dds_H3p3)
norm_H3p3 <- DESeq2::counts(dds_H3p3,normalized=TRUE) #DEGを取った後のクラスタリングに使う。

normalizedcount_H3p3 <- as.data.frame(norm_H3p3) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_1$sample))
filename <- paste(csvfilepath,"_normcount_H3p3.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3p3.csv"
readr::write_csv(normalizedcount_H3p3, filename)
nrow(normalizedcount_H3p3)
[1] 55450
ncol(normalizedcount_H3p3)
[1] 17
norm_gene_H3p3 <- normalizedcount_H3p3 %>% inner_join(ensemble) %>% dplyr::select("ens_gene","ext_gene", "biotype","chr", all_of(def_list_select_1$sample))
Joining, by = "ens_gene"
filename <- paste(csvfilepath,"_normcount_H3p3_genename.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3p3_genename.csv"
readr::write_csv(norm_gene_H3p3, filename)
nrow(norm_gene_H3p3)
[1] 55197
ncol(norm_gene_H3p3)
[1] 20
# H3K27ac
dds_H3K27ac <- DESeq2::estimateSizeFactors(dds_H3K27ac)
norm_H3K27ac <- DESeq2::counts(dds_H3K27ac,normalized=TRUE) #DEGを取った後のクラスタリングに使う。

normalizedcount_H3K27ac <- as.data.frame(norm_H3K27ac) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_2$sample))
filename <- paste(csvfilepath,"_normcount_H3K27ac.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3K27ac.csv"
readr::write_csv(normalizedcount_H3K27ac, filename)
nrow(normalizedcount_H3K27ac)
[1] 55450
ncol(normalizedcount_H3K27ac)
[1] 17
norm_gene_H3K27ac <- normalizedcount_H3K27ac %>% inner_join(ensemble) %>% dplyr::select("ens_gene","ext_gene", "biotype","chr", all_of(def_list_select_2$sample))
Joining, by = "ens_gene"
filename <- paste(csvfilepath,"_normcount_H3K27ac_genename.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3K27ac_genename.csv"
readr::write_csv(norm_gene_H3K27ac, filename)
nrow(norm_gene_H3K27ac)
[1] 55197
ncol(norm_gene_H3K27ac)
[1] 20
# H3K4me3
dds_H3K4me3 <- DESeq2::estimateSizeFactors(dds_H3K4me3)
norm_H3K4me3 <- DESeq2::counts(dds_H3K4me3,normalized=TRUE) #DEGを取った後のクラスタリングに使う。

normalizedcount_H3K4me3 <- as.data.frame(norm_H3K4me3) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_3$sample))
filename <- paste(csvfilepath,"_normcount_H3K4me3.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3K4me3.csv"
readr::write_csv(normalizedcount_H3K4me3, filename)
nrow(normalizedcount_H3K4me3)
[1] 55450
ncol(normalizedcount_H3K4me3)
[1] 17
norm_gene_H3K4me3 <- normalizedcount_H3K4me3 %>% inner_join(ensemble) %>% dplyr::select("ens_gene","ext_gene", "biotype","chr", all_of(def_list_select_3$sample))
Joining, by = "ens_gene"
filename <- paste(csvfilepath,"_normcount_H3K4me3_genename.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3K4me3_genename.csv"
readr::write_csv(norm_gene_H3K4me3, filename)
nrow(norm_gene_H3K4me3)
[1] 55197
ncol(norm_gene_H3K4me3)
[1] 20
# H3K27me3
dds_H3K27me3 <- DESeq2::estimateSizeFactors(dds_H3K27me3)
norm_H3K27me3 <- DESeq2::counts(dds_H3K27me3,normalized=TRUE) #DEGを取った後のクラスタリングに使う。

normalizedcount_H3K27me3 <- as.data.frame(norm_H3K27me3) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_4$sample))
filename <- paste(csvfilepath,"_normcount_H3K27me3.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3K27me3.csv"
readr::write_csv(normalizedcount_H3K27me3, filename)
nrow(normalizedcount_H3K27me3)
[1] 55450
ncol(normalizedcount_H3K27me3)
[1] 17
norm_gene_H3K27me3 <- normalizedcount_H3K27me3 %>% inner_join(ensemble) %>% dplyr::select("ens_gene","ext_gene", "biotype","chr", all_of(def_list_select_4$sample))
Joining, by = "ens_gene"
filename <- paste(csvfilepath,"_normcount_H3K27me3_genename.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_H3K27me3_genename.csv"
readr::write_csv(norm_gene_H3K27me3, filename)
nrow(norm_gene_H3K27me3)
[1] 55197
ncol(norm_gene_H3K27me3)
[1] 20
# bind norm count
normalizedcount <- normalizedcount_ATAC %>% inner_join(normalizedcount_H3p3) %>% inner_join(normalizedcount_H3K27ac) %>% inner_join(normalizedcount_H3K4me3) %>% inner_join(normalizedcount_H3K27me3)
Joining, by = "ens_gene"
Joining, by = "ens_gene"
Joining, by = "ens_gene"
Joining, by = "ens_gene"
norm_gene <- norm_gene_ATAC %>% inner_join(norm_gene_H3p3) %>% inner_join(norm_gene_H3K27ac) %>% inner_join(norm_gene_H3K4me3) %>% inner_join(norm_gene_H3K27me3)
Joining, by = c("ens_gene", "ext_gene", "biotype", "chr")
Joining, by = c("ens_gene", "ext_gene", "biotype", "chr")
Joining, by = c("ens_gene", "ext_gene", "biotype", "chr")
Joining, by = c("ens_gene", "ext_gene", "biotype", "chr")
print(norm_gene)
colnames(norm_gene)
 [1] "ens_gene"                "ext_gene"                "biotype"                 "chr"                     "ATAC_UI_DoxMinus_1"     
 [6] "ATAC_UI_DoxMinus_2"      "ATAC_UI_DoxMinus_3"      "ATAC_UI_DoxMinus_4"      "ATAC_UI_DoxPlus_1"       "ATAC_UI_DoxPlus_2"      
[11] "ATAC_UI_DoxPlus_3"       "ATAC_UI_DoxPlus_4"       "ATAC_48h_DoxMinus_1"     "ATAC_48h_DoxMinus_2"     "ATAC_48h_DoxMinus_3"    
[16] "ATAC_48h_DoxMinus_4"     "ATAC_48h_DoxPlus_1"      "ATAC_48h_DoxPlus_2"      "ATAC_48h_DoxPlus_3"      "ATAC_48h_DoxPlus_4"     
[21] "H3p3_UI_DoxMinus_1"      "H3p3_UI_DoxMinus_2"      "H3p3_UI_DoxPlus_1"       "H3p3_UI_DoxPlus_2"       "H3p3_0h_DoxMinus_1"     
[26] "H3p3_0h_DoxMinus_2"      "H3p3_0h_DoxPlus_1"       "H3p3_0h_DoxPlus_2"       "H3p3_24h_DoxMinus_1"     "H3p3_24h_DoxMinus_2"    
[31] "H3p3_24h_DoxPlus_1"      "H3p3_24h_DoxPlus_2"      "H3p3_48h_DoxMinus_1"     "H3p3_48h_DoxMinus_2"     "H3p3_48h_DoxPlus_1"     
[36] "H3p3_48h_DoxPlus_2"      "H3K27ac_UI_DoxMinus_1"   "H3K27ac_UI_DoxMinus_2"   "H3K27ac_UI_DoxPlus_1"    "H3K27ac_UI_DoxPlus_2"   
[41] "H3K27ac_0h_DoxMinus_1"   "H3K27ac_0h_DoxMinus_2"   "H3K27ac_0h_DoxPlus_1"    "H3K27ac_0h_DoxPlus_2"    "H3K27ac_24h_DoxMinus_1" 
[46] "H3K27ac_24h_DoxMinus_2"  "H3K27ac_24h_DoxPlus_1"   "H3K27ac_24h_DoxPlus_2"   "H3K27ac_48h_DoxMinus_1"  "H3K27ac_48h_DoxMinus_2" 
[51] "H3K27ac_48h_DoxPlus_1"   "H3K27ac_48h_DoxPlus_2"   "H3K4me3_UI_DoxMinus_1"   "H3K4me3_UI_DoxMinus_2"   "H3K4me3_UI_DoxPlus_1"   
[56] "H3K4me3_UI_DoxPlus_2"    "H3K4me3_0h_DoxMinus_1"   "H3K4me3_0h_DoxMinus_2"   "H3K4me3_0h_DoxPlus_1"    "H3K4me3_0h_DoxPlus_2"   
[61] "H3K4me3_24h_DoxMinus_1"  "H3K4me3_24h_DoxMinus_2"  "H3K4me3_24h_DoxPlus_1"   "H3K4me3_24h_DoxPlus_2"   "H3K4me3_48h_DoxMinus_1" 
[66] "H3K4me3_48h_DoxMinus_2"  "H3K4me3_48h_DoxPlus_1"   "H3K4me3_48h_DoxPlus_2"   "H3K27me3_UI_DoxMinus_1"  "H3K27me3_UI_DoxMinus_2" 
[71] "H3K27me3_UI_DoxPlus_1"   "H3K27me3_UI_DoxPlus_2"   "H3K27me3_0h_DoxMinus_1"  "H3K27me3_0h_DoxMinus_2"  "H3K27me3_0h_DoxPlus_1"  
[76] "H3K27me3_0h_DoxPlus_2"   "H3K27me3_24h_DoxMinus_1" "H3K27me3_24h_DoxMinus_2" "H3K27me3_24h_DoxPlus_1"  "H3K27me3_24h_DoxPlus_2" 
[81] "H3K27me3_48h_DoxMinus_1" "H3K27me3_48h_DoxMinus_2" "H3K27me3_48h_DoxPlus_1"  "H3K27me3_48h_DoxPlus_2" 
filename <- paste(csvfilepath,"_normcount.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount.csv"
readr::write_csv(normalizedcount, filename)

filename <- paste(csvfilepath,"_normcount_genename.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__normcount_genename.csv"
readr::write_csv(norm_gene, filename)

size factors を書き出し


filename <- paste(csvfilepath,"_sizefactors_ATAC.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__sizefactors_ATAC.csv"
as.data.frame(DESeq2::sizeFactors(dds_ATAC))  %>% tibble::rownames_to_column("sample") %>% readr::write_csv(filename)

filename <- paste(csvfilepath,"_sizefactors_H3p3.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__sizefactors_H3p3.csv"
as.data.frame(DESeq2::sizeFactors(dds_H3p3))  %>% tibble::rownames_to_column("sample") %>% readr::write_csv(filename)

filename <- paste(csvfilepath,"_sizefactors_H3K27ac.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__sizefactors_H3K27ac.csv"
as.data.frame(DESeq2::sizeFactors(dds_H3K27ac))  %>% tibble::rownames_to_column("sample") %>% readr::write_csv(filename)

filename <- paste(csvfilepath,"_sizefactors_H3K4me3.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__sizefactors_H3K4me3.csv"
as.data.frame(DESeq2::sizeFactors(dds_H3K4me3))  %>% tibble::rownames_to_column("sample") %>% readr::write_csv(filename)

filename <- paste(csvfilepath,"_sizefactors_H3K27me3.csv",sep="_")
print(filename)
[1] "TSS_pm5kb_20200624__sizefactors_H3K27me3.csv"
as.data.frame(DESeq2::sizeFactors(dds_H3K27me3))  %>% tibble::rownames_to_column("sample") %>% readr::write_csv(filename)

vst => z score


vsd_ATAC <- DESeq2::vst(dds_ATAC) #normalized countが入っている。(vstかrlog)
Xd_ATAC <- SummarizedExperiment::assay(vsd_ATAC) # 全て選択(200326) 20190920を元に (191024)
Xs_ATAC <- Xd_ATAC %>% t %>% scale %>% t

vsd_H3p3 <- DESeq2::vst(dds_H3p3) #normalized countが入っている。(vstかrlog)
Xd_H3p3 <- SummarizedExperiment::assay(vsd_H3p3) # 全て選択(200326) 20190920を元に (191024)
Xs_H3p3 <- Xd_H3p3 %>% t %>% scale %>% t

vsd_H3K27ac <- DESeq2::vst(dds_H3K27ac) #normalized countが入っている。(vstかrlog)
Xd_H3K27ac <- SummarizedExperiment::assay(vsd_H3K27ac) # 全て選択(200326) 20190920を元に (191024)
Xs_H3K27ac <- Xd_H3K27ac %>% t %>% scale %>% t

vsd_H3K4me3 <- DESeq2::vst(dds_H3K4me3) #normalized countが入っている。(vstかrlog)
Xd_H3K4me3 <- SummarizedExperiment::assay(vsd_H3K4me3) # 全て選択(200326) 20190920を元に (191024)
Xs_H3K4me3 <- Xd_H3K4me3 %>% t %>% scale %>% t

vsd_H3K27me3 <- DESeq2::vst(dds_H3K27me3) #normalized countが入っている。(vstかrlog)
Xd_H3K27me3 <- SummarizedExperiment::assay(vsd_H3K27me3) # 全て選択(200326) 20190920を元に (191024)
Xs_H3K27me3 <- Xd_H3K27me3 %>% t %>% scale %>% t

vsdtrans_ATAC <- as.data.frame(Xd_ATAC) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_0$sample))
filename <- paste(csvfilepath,"_vstrans_ATAC.csv",sep="_")
readr::write_csv(vsdtrans_ATAC, filename)
nrow(vsdtrans_ATAC)
[1] 55450
ncol(vsdtrans_ATAC)
[1] 17
vsdtrans_H3p3 <- as.data.frame(Xd_H3p3) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_1$sample))
filename <- paste(csvfilepath,"_vstrans_H3p3.csv",sep="_")
readr::write_csv(vsdtrans_H3p3, filename)
nrow(vsdtrans_H3p3)
[1] 55450
ncol(vsdtrans_H3p3)
[1] 17
vsdtrans_H3K27ac <- as.data.frame(Xd_H3K27ac) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_2$sample))
filename <- paste(csvfilepath,"_vstrans_H3K27ac.csv",sep="_")
readr::write_csv(vsdtrans_H3K27ac, filename)
nrow(vsdtrans_H3K27ac)
[1] 55450
ncol(vsdtrans_H3K27ac)
[1] 17
vsdtrans_H3K4me3 <- as.data.frame(Xd_H3K4me3) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_3$sample))
filename <- paste(csvfilepath,"_vstrans_H3K4me3.csv",sep="_")
readr::write_csv(vsdtrans_H3K4me3, filename)
nrow(vsdtrans_H3K4me3)
[1] 55450
ncol(vsdtrans_H3K4me3)
[1] 17
vsdtrans_H3K27me3 <- as.data.frame(Xd_H3K27me3) %>% tibble::rownames_to_column("ens_gene") %>% as_tibble %>% dplyr::select("ens_gene", all_of(def_list_select_4$sample))
filename <- paste(csvfilepath,"_vstrans_H3K27me3.csv",sep="_")
readr::write_csv(vsdtrans_H3K27me3, filename)
nrow(vsdtrans_H3K27me3)
[1] 55450
ncol(vsdtrans_H3K27me3)
[1] 17
zscore_ATAC <- Xs_ATAC  %>% as.data.frame() %>% tibble::rownames_to_column("ens_gene") %>% as_tibble
zscore_H3p3 <- Xs_H3p3  %>% as.data.frame() %>% tibble::rownames_to_column("ens_gene") %>% as_tibble
zscore_H3K27ac <- Xs_H3K27ac  %>% as.data.frame() %>% tibble::rownames_to_column("ens_gene") %>% as_tibble
zscore_H3K4me3 <- Xs_H3K4me3  %>% as.data.frame() %>% tibble::rownames_to_column("ens_gene") %>% as_tibble
zscore_H3K27me3 <- Xs_H3K27me3  %>% as.data.frame() %>% tibble::rownames_to_column("ens_gene") %>% as_tibble

zscore <- zscore_ATAC %>% inner_join(zscore_H3p3) %>% inner_join(zscore_H3K27ac) %>% inner_join(zscore_H3K4me3) %>% inner_join(zscore_H3K27me3)
Joining, by = "ens_gene"
Joining, by = "ens_gene"
Joining, by = "ens_gene"
Joining, by = "ens_gene"
readr::write_csv(zscore, paste(csvfilepath,"_zscore_All.csv",sep="_"))

zscore_type <- zscore  %>% inner_join(ensemble) %>% dplyr::select("ens_gene","ext_gene", "biotype","chr", all_of(def_list_select$sample))
Joining, by = "ens_gene"

norm後の分布

normalized count, zscore の分布 (20191017修正)


norm_plotlist_all <- normalizedcount %>% gather("sample", "normalized",-(ens_gene)) %>% inner_join(def_list_select, by = "sample")
norm_plot_all <- norm_plotlist_all %>% 
ggplot(aes(time_replicate,normalized,group=time_replicate,colour=type))+geom_violin(scale="count")+geom_boxplot(width=.1,)+facet_wrap(~seq*type,ncol=2)+theme_bw()+ theme(strip.text = element_text(size = 12),axis.text.x = element_text(hjust = 0.5,vjust = 0.5)) + ggtitle(paste(folder_name, "(all, normalized count)")) + scale_y_log10(limits = c(0.1,NA)) 

#+ggsci::scale_color_d3("category20")

print(norm_plot_all)




ggsave(plot=norm_plot_all,file="./NormCount.pdf", width = 20, height = 15, dpi = 360, limitsize = FALSE)

QC

Total reads

20191016修正, 20200623修正


chr_chart <- matome5 %>% dplyr::select(ens_gene,chr) %>% group_by(ens_gene,chr) %>% summarize() %>% ungroup() 
`summarise()` regrouping output by 'ens_gene' (override with `.groups` argument)
#chr_chart <- bedfile %>% dplyr::select(ens_gene,chr)  %>% group_by(ens_gene,chr) %>% summarize() %>% ungroup() #20191016修正

#> right_join(chr_chart, matome5, by="ens_gene")
# A tibble: 55,456 x 14

#bychr<- left_join(matome5, chr_chart, by="ens_gene") %>% dplyr::select(-(ens_gene)) %>%
#  gather("sample","count",-chr) %>%
#  group_by(chr,sample) %>% summarise(total=sum(count)) %>% ungroup

#mat <- left_join(matome5, chr_chart, by="ens_gene")

#bychr <- mat %>% dplyr::select(-(ens_gene)) %>%
#  gather("sample","count",-chr) %>%
#  group_by(chr,sample) %>% summarise(total=sum(count))  %>% f_sample() %>% ungroup

bychr <- matome5 %>% dplyr::select(chr,def_list_select$sample) %>%
  gather("sample","count",-chr) %>%
  group_by(chr,sample) %>% summarise(total=sum(count))  %>% f_sample() %>% ungroup
`summarise()` regrouping output by 'chr' (override with `.groups` argument)
ggplot(bychr,aes(reorder(sample,dplyr::desc(sample)),total/1e6,fill=chr)) +
  theme_linedraw() + geom_bar(stat="identity") + coord_flip() +
  xlab("sample") + ylab("million reads") + ggsci::scale_fill_igv() +
  scale_x_discrete(limits = rev(levels(sample)))

NA
NA
NA
NA

normalized count


mat_normcount <- left_join(normalizedcount, chr_chart, by="ens_gene")

bychr_mat_normcount <- mat_normcount %>% dplyr::select(-(ens_gene)) %>%
  gather("sample","normcount",-chr) %>%
  group_by(chr,sample) %>% summarise(normtotal=sum(normcount)) %>% f_sample() %>% ungroup
`summarise()` regrouping output by 'chr' (override with `.groups` argument)
ggplot(bychr_mat_normcount,aes(reorder(sample,dplyr::desc(sample)),normtotal/1e6,fill=chr)) +
  theme_linedraw() + geom_bar(stat="identity") + coord_flip() +
  xlab("sample") + ylab("normalized counts (million reads)") + ggsci::scale_fill_igv() +
  scale_x_discrete(limits = rev(levels(sample)))

Correlations

drop rows with all 0 -> +1/2 -> geom.scale -> log -> Pearson’s

#matf_Correlation <- mat %>% filter(chr!="chrM") %>% dplyr::select(-"chr") %>% filter_at(-(1),any_vars(. > 0))

matf_Correlation <- matome5 %>% dplyr::select(chr,def_list_select$sample) %>% filter(chr!="chrM") %>% dplyr::select(-"chr") %>% filter_at(-(1),any_vars(. > 0))

X_Correlation <- matf_Correlation %>% dplyr::select(-(1)) %>% as.matrix
rownames(X_Correlation) <- matf_Correlation$ens_gene
Unknown or uninitialised column: `ens_gene`.
lX_Correlation <- log(gscale(X_Correlation+0.5))
R <- cor(lX_Correlation); diag(R) <- NA
pheatmap::pheatmap(R,color=viridis::viridis(256))


#X <- matf %>% dplyr::select(-(1:4)) %>% as.matrix
#rownames(X) <- matf$ens_gene
#lX <- log(gscale(X+0.5))
#R <- cor(lX); diag(R) <- NA
#pheatmap::pheatmap(R,color=viridis::viridis(256))

###--- DESeq2によりnormalized count ---###
#model<- ~group
#dds_Correlation <- DESeq2::DESeqDataSetFromMatrix(X_Correlation[,def_list_select$sample],def_list_select,model) #必要なサンプルのみ
#dds_Correlation <- DESeq2::DESeqDataSetFromMatrix(X_Correlation[,def_list$sample],def_list,model)
#dds_Correlation <- DESeq2::estimateSizeFactors(dds_Correlation)
#norm_Correlation <- DESeq2::counts(dds_Correlation,normalized=TRUE) #normにnarmalized countが入る。

Dimension reduction

# set scale=TRUE if the patterns (not level) is the matter
p <- prcomp(t(lX_Correlation[rank(-apply(lX_Correlation,1,var)) <= ntop,]),scale=scalerows,center=TRUE)
screeplot(p,las=2,main="Importance")

print(summary(p)$imp[,seq(min(10,ncol(X_Correlation)))])
                            PC1      PC2      PC3      PC4       PC5       PC6       PC7       PC8       PC9      PC10
Standard deviation     22.17018 1.317342 1.075728 0.783874 0.6637618 0.6246527 0.6047705 0.5830881 0.5684595 0.5323901
Proportion of Variance  0.98303 0.003470 0.002310 0.001230 0.0008800 0.0007800 0.0007300 0.0006800 0.0006500 0.0005700
Cumulative Proportion   0.98303 0.986500 0.988820 0.990050 0.9909300 0.9917100 0.9924400 0.9931200 0.9937700 0.9943300
label_Correlation <- def_list_select %>% filter(sample %in% colnames(X_Correlation))
df <- data.frame(p$x) %>% as_tibble(rownames="sample") %>%
  inner_join(label_Correlation,.)
Joining, by = "sample"
print(df)

QC 終了

Calculate log2 FC


#------- setting -------#
fdr <- 0.1 # acceptable false discovery rate (固定)
lfcthreth <- log2(1) # threshold in abs(log2FC)
# controls should be placed in the right

plot_title1 <- "2gun"


contrast_H3p3 <- list(
  #Intercept = list("Intercept"),
  group_H3p3_UI_Doxplus_vs_minus = c("group", "H3p3_UI_DoxPlus","H3p3_UI_DoxMinus"),
  group_H3p3_0h_Doxplus_vs_minus = c("group","H3p3_0h_DoxPlus", "H3p3_0h_DoxMinus"),
  group_H3p3_24h_Doxplus_vs_minus = c("group","H3p3_24h_DoxPlus", "H3p3_24h_DoxMinus"),
  group_H3p3_48h_Doxplus_vs_minus = c("group","H3p3_48h_DoxPlus", "H3p3_48h_DoxMinus")
)



contrast_H3K4me3 <- list(
  #Intercept = list("Intercept"),
  group_H3K4me3_UI_Doxplus_vs_minus = c("group", "H3K4me3_UI_DoxPlus","H3K4me3_UI_DoxMinus"),
  group_H3K4me3_0h_Doxplus_vs_minus = c("group","H3K4me3_0h_DoxPlus", "H3K4me3_0h_DoxMinus"),
  group_H3K4me3_24h_Doxplus_vs_minus = c("group","H3K4me3_24h_DoxPlus", "H3K4me3_24h_DoxMinus"),
  group_H3K4me3_48h_Doxplus_vs_minus = c("group","H3K4me3_48h_DoxPlus", "H3K4me3_48h_DoxMinus")
)

contrast_H3K27ac <- list(
  #Intercept = list("Intercept"),
  group_H3K27ac_UI_Doxplus_vs_minus = c("group", "H3K27ac_UI_DoxPlus","H3K27ac_UI_DoxMinus"),
  group_H3K27ac_0h_Doxplus_vs_minus = c("group","H3K27ac_0h_DoxPlus", "H3K27ac_0h_DoxMinus"),
  group_H3K27ac_24h_Doxplus_vs_minus = c("group","H3K27ac_24h_DoxPlus", "H3K27ac_24h_DoxMinus"),
  group_H3K27ac_48h_Doxplus_vs_minus = c("group","H3K27ac_48h_DoxPlus", "H3K27ac_48h_DoxMinus")
)


contrast_H3K27me3 <- list(
  #Intercept = list("Intercept"),
  group_H3K27me3_UI_Doxplus_vs_minus = c("group", "H3K27me3_UI_DoxPlus","H3K27me3_UI_DoxMinus"),
  group_H3K27me3_0h_Doxplus_vs_minus = c("group","H3K27me3_0h_DoxPlus", "H3K27me3_0h_DoxMinus"),
  group_H3K27me3_24h_Doxplus_vs_minus = c("group","H3K27me3_24h_DoxPlus", "H3K27me3_24h_DoxMinus"),
  group_H3K27me3_48h_Doxplus_vs_minus = c("group","H3K27me3_48h_DoxPlus", "H3K27me3_48h_DoxMinus")
)

contrast_ATAC <- list(
  #Intercept = list("Intercept"),
  group_ATAC_UI_Doxplus_vs_minus = c("group", "ATAC_UI_DoxPlus","ATAC_UI_DoxMinus"),
  group_ATAC_48h_Doxplus_vs_minus = c("group","ATAC_48h_DoxPlus", "ATAC_48h_DoxMinus")
)

# BRB
#  group_UI_Doxplus_vs_minus = c("group", "BRB_UI_DoxPlus", "BRB_UI_DoxMinus"),
#  group_0h_Doxplus_vs_minus = c("group", "BRB_0h_DoxPlus", "BRB_0h_DoxMinus"),
#  group_24h_Doxplus_vs_minus = c("group", "BRB_24h_DoxPlus", "BRB_24h_DoxMinus"),
#  group_48h_Doxplus_vs_minus = c("group", "BRB_48h_DoxPlus", "BRB_48h_DoxMinus")
  


#-----------------------#

#-------------- 自動 --------------------------------------------------#
#-- ファイル名 の設定 ---#
#folder_name_plot0 <- paste(".",folder_name, paste(folder_name,plot_title1,sep="_"),"",sep="/")
#folder_name_plot_path <- paste(folder_name_plot0,paste(folder_name,plot_title1,"",sep="_"),sep="")

log2 FC のみ計算 (DEGは特に出さない)



res_H3p3 <- mapply(function(x)
  DESeq2::results(dds_H3p3,x,lfcThreshold=lfcthreth,alpha=fdr)
,contrast_H3p3)

res_H3K4me3 <- mapply(function(x)
  DESeq2::results(dds_H3K4me3,x,lfcThreshold=lfcthreth,alpha=fdr)
,contrast_H3K4me3)

res_H3K27ac <- mapply(function(x)
  DESeq2::results(dds_H3K27ac,x,lfcThreshold=lfcthreth,alpha=fdr)
,contrast_H3K27ac)


res_H3K27me3 <- mapply(function(x)
  DESeq2::results(dds_H3K27me3,x,lfcThreshold=lfcthreth,alpha=fdr)
,contrast_H3K27me3)


res_ATAC <- mapply(function(x)
  DESeq2::results(dds_ATAC,x,lfcThreshold=lfcthreth,alpha=fdr)
,contrast_ATAC)



print(fdr)
[1] 0.1

re_H3p3_all <- map(res_H3p3,as_tibble,rownames="ens_gene") %>%
  tibble(aspect=factor(names(.),names(.)),data=.) %>%
  mutate(data=map(data,annotate)) %>%
  unnest(cols = "data")

re_H3K4me3_all <- map(res_H3K4me3,as_tibble,rownames="ens_gene") %>%
  tibble(aspect=factor(names(.),names(.)),data=.) %>%
  mutate(data=map(data,annotate)) %>%
  unnest(cols = "data")

re_H3K27ac_all <- map(res_H3K27ac,as_tibble,rownames="ens_gene") %>%
  tibble(aspect=factor(names(.),names(.)),data=.) %>%
  mutate(data=map(data,annotate)) %>%
  unnest(cols = "data")

re_H3K27me3_all <- map(res_H3K27me3,as_tibble,rownames="ens_gene") %>%
  tibble(aspect=factor(names(.),names(.)),data=.) %>%
  mutate(data=map(data,annotate)) %>%
  unnest(cols = "data")

re_ATAC_all <- map(res_ATAC,as_tibble,rownames="ens_gene") %>%
  tibble(aspect=factor(names(.),names(.)),data=.) %>%
  mutate(data=map(data,annotate)) %>%
  unnest(cols = "data")


filename <- paste("./2gun/",csvfilepath,"_resultsall_fdr0p1_H3p3.csv",sep="")
print(filename)
[1] "./2gun/TSS_pm5kb_20200624_resultsall_fdr0p1_H3p3.csv"
readr::write_csv(re_H3p3_all,filename)
nrow(re_H3p3_all)
[1] 221800
filename <- paste("./2gun/",csvfilepath,"_resultsall_fdr0p1_H3K4me3.csv",sep="")
print(filename)
[1] "./2gun/TSS_pm5kb_20200624_resultsall_fdr0p1_H3K4me3.csv"
readr::write_csv(re_H3K4me3_all,filename)
nrow(re_H3K4me3_all)
[1] 221800
filename <- paste("./2gun/",csvfilepath,"_resultsall_fdr0p1_H3K27ac.csv",sep="")
print(filename)
[1] "./2gun/TSS_pm5kb_20200624_resultsall_fdr0p1_H3K27ac.csv"
readr::write_csv(re_H3K27ac_all,filename)
nrow(re_H3K27ac_all)
[1] 221800
filename <- paste("./2gun/",csvfilepath,"_resultsall_fdr0p1_H3K27me3.csv",sep="")
print(filename)
[1] "./2gun/TSS_pm5kb_20200624_resultsall_fdr0p1_H3K27me3.csv"
readr::write_csv(re_H3K27me3_all,filename)
nrow(re_H3K27me3_all)
[1] 221800
filename <- paste("./2gun/",csvfilepath,"_resultsall_fdr0p1_ATAC.csv",sep="")
print(filename)
[1] "./2gun/TSS_pm5kb_20200624_resultsall_fdr0p1_ATAC.csv"
readr::write_csv(re_ATAC_all,filename)
nrow(re_ATAC_all)
[1] 110900

Clustering (all genes)

clustering H3.3

#20191205修正と作成



cluster_number <- 6


##--------- clustering -----------#
set.seed(3)

# H3.3で
 
zscore_H3p3_s <- zscore_type %>% dplyr::select("ens_gene",all_of(def_list_select_1$sample))  %>% filter(across(where(is_double), ~ (.x != 0)|(.x == 0)))
#zscore_H3p3_s <- zscore_H3p3 %>% filter(across(where(is_double), ~ (.x != 0)|(.x == 0)))

nrow(zscore_type)
[1] 55197
nrow(zscore_H3p3_s)
[1] 52326
Xs_H3p3 <- zscore_H3p3_s %>% dplyr::select(-ens_gene) %>% as.matrix()
rownames(Xs_H3p3) <- zscore_H3p3_s$ens_gene

km_allH3p3 <- kmeans(Xs_H3p3,cluster_number,nstart = 25,algorithm = "Lloyd")
 10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした  10 回の反復を行いましたが収束しませんでした 
kmc_allH3p3 <- km_allH3p3$centers %>% as_tibble(rownames="cluster") %>% gather(sample,val,-cluster) %>% inner_join(def_list_select)
Joining, by = "sample"
kmc_allH3p3_group <- kmc_allH3p3

#kmc_LRT_group <- kmc_LRT %>% mutate(growth=factor(growth, c("UI","Diff0h","Diff24h","Diff48h"))) %>% mutate(type=factor(type, c("Doxplus","Doxminus")))

#kmc_LRT_group <- kmc_LRT_group %>% mutate(time=case_when(growth=="UI" ~"UI",growth=="Diff0h"~"0h",growth=="Diff24h"~"24h",growth=="Diff48h"~"48h",TRUE~"error"))
#kmc_LRT_group <- kmc_LRT_group %>% mutate(time=factor(time, c("UI","0h","24h","48h")))

#gggglabel <- paste("k-means: Total",nrow(Xs_H3p3),"[1]",km_allH3p3$size[1],"[2]",km_allH3p3$size[2],"[3]",km_allH3p3$size[3],"[4]",km_allH3p3$size[4],"[5]",km_allH3p3$size[5],"[6]",km_allH3p3$size[6],sep=" ")

gggglabel <- paste("Original",nrow(zscore_type),"H3.3 k-means: Total",nrow(Xs_H3p3),"[1]",km_allH3p3$size[1],"[2]",km_allH3p3$size[2],"[3]",km_allH3p3$size[3],"[4]",km_allH3p3$size[4],"[5]",km_allH3p3$size[5],"[6]",km_allH3p3$size[6],sep=" ")

#------- size -------#

print(km_allH3p3$size) 
[1]  8017  8143 10775  8039  7716  9636
#rrres_allH3p3 <- km_allH3p3$cluster %>% tibble(ens_gene=names(.),cluster=.) %>% left_join(zscore_type_clus3,.) %>% arrange(cluster) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,cluster,all_of(def_list_select$sample))

rrres_allH3p3 <- km_allH3p3$cluster %>% tibble(ens_gene=names(.),cluster=.) %>% left_join(.,zscore_type) %>% arrange(cluster) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,cluster,all_of(def_list_select$sample))
Joining, by = "ens_gene"
#rrres_allH3p3 <- km_allH3p3$cluster %>% tibble(ens_gene=names(.),cluster=.) %>% left_join(zscore_type,.) %>% arrange(cluster) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,cluster,all_of(def_list_select$sample))

#rrres_LRT <- km_LRT$cluster %>% tibble(ens_gene=names(.),cluster=.) %>% right_join(e2g,.) %>% arrange(cluster)

file_path <- paste("./H3p3allcluster/", csvfilepath, "_kmeans_cluster.csv",sep="") 
readr::write_csv(rrres_allH3p3,file_path)

##------- PCA -------#

pcacluster_save <- prcomp(Xs_H3p3)$x %>% as_tibble %>% dplyr::select(PC1,PC2) %>% mutate(cluster=km_allH3p3$cluster) %>% ggplot(aes(PC1,PC2,colour=factor(cluster)))+geom_point(size=1.5,alpha=0.6)+coord_fixed()+theme_linedraw()+ggsci::scale_color_d3("category20")

file_path <- paste("./H3p3allcluster/", csvfilepath, "_kmeans__pcacluster_PC1PC2.pdf",sep="") 
ggsave(plot=pcacluster_save,file=file_path, width = 10, height = 6, dpi = 120)
print(pcacluster_save)


pcacluster_save <- prcomp(Xs_H3p3)$x %>% as_tibble %>% dplyr::select(PC1,PC3) %>% mutate(cluster=km_allH3p3$cluster) %>% ggplot(aes(PC1,PC3,colour=factor(cluster)))+geom_point(size=1.5,alpha=0.6)+coord_fixed()+theme_linedraw()+ggsci::scale_color_d3("category20")

file_path <- paste("./H3p3allcluster/", csvfilepath, "_kmeans__pcacluster_PC1PC3.pdf",sep="") 
ggsave(plot=pcacluster_save,file=file_path, width = 10, height = 6, dpi = 120)
print(pcacluster_save)



#================================================#
# mouseCTX 0438を参考に。

#------------------#
f_cluster <- function(x) x %>% group_by(group, type, time, cluster, seq) %>% summarise(avg=mean(val),se=sd(val)/sqrt(length(val))) %>% ungroup()
print(kmc_allH3p3_group %>% group_by(group, type, time) %>% summarise())
`summarise()` regrouping output by 'group', 'type' (override with `.groups` argument)
f_clusterp <- function(x) x %>% group_by(group, type, time, cluster, sep) %>% summarise(avg=mean(val),se=sd(val)/sqrt(length(val))) %>% ungroup()
print(kmc_allH3p3_group %>% group_by(group, type, time) %>% summarise()) #作図用
`summarise()` regrouping output by 'group', 'type' (override with `.groups` argument)
#-------#

cluster_save <- kmc_allH3p3_group %>%
ggplot(aes(time,val,group=type,colour=type))+ geom_abline(intercept=0,slope=0,linetype="dashed",colour="gray") +geom_line(aes(x=time,y=avg,colour=type),data=f_cluster)+geom_point()+facet_wrap(~cluster*seq,ncol=3)+ggsci::scale_color_npg()+theme_bw()+ theme(strip.text = element_text(size = 12),axis.text.x = element_text(vjust = 0.5), strip.background = element_blank(),  plot.title=element_text(size=5))  + ggtitle(gggglabel)+ggsci::scale_color_npg()  + ylab("z score")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
file_path <- paste("./H3p3allcluster/", csvfilepath, "_cluster_type.pdf",sep="") 
ggsave(plot=cluster_save,file=file_path, width = 6, height = 6, dpi = 120)
#ggsave(plot=cluster_save,file=file_path, width = 6, height = 6, dpi = 120)
print(cluster_save)


#================================================#
z_H3p3clus1 <- rrres_allH3p3 %>% filter(cluster=="1") %>% dplyr::rename(H3p3clus=cluster)
z_H3p3clus2 <- rrres_allH3p3 %>% filter(cluster=="2") %>% dplyr::rename(H3p3clus=cluster)
z_H3p3clus3 <- rrres_allH3p3 %>% filter(cluster=="3") %>% dplyr::rename(H3p3clus=cluster)
z_H3p3clus4 <- rrres_allH3p3 %>% filter(cluster=="4") %>% dplyr::rename(H3p3clus=cluster)
z_H3p3clus5 <- rrres_allH3p3 %>% filter(cluster=="5") %>% dplyr::rename(H3p3clus=cluster)
z_H3p3clus6 <- rrres_allH3p3 %>% filter(cluster=="6") %>% dplyr::rename(H3p3clus=cluster)

nrow(rrres_allH3p3)
[1] 52326
nrow(z_H3p3clus1)
[1] 8017
nrow(z_H3p3clus2)
[1] 8143
nrow(z_H3p3clus3)
[1] 10775
nrow(z_H3p3clus4)
[1] 8039
nrow(z_H3p3clus5)
[1] 7716
nrow(z_H3p3clus6)
[1] 9636
nrow(rrres_allH3p3 %>% filter(is.na(cluster)))
[1] 0
rrres_allH3p3 %>% filter(ext_gene %in% c("Myh3","Ckm","Acta1","Tnnt2","Actb","Csrp3","Tpm2","Nsdhl","Myog"))


BRB result


cluster_num <- 4 

##---- BRBのクラスタリング(LRT) の結果 -------#
#filepath_BRBcluster <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/LRT/DEG_fdr0p1__BRB0432lane2noumi_H3mm18_Dox_kmeans4__cluster_result.csv" #BRB等のDEGのリスト
#filepath_BRBallgene <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/H3mm18KO_3T3_Dox_normCount_genename.csv" #BRB等のDEGのリスト
#filepath_BRBzscore <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/LRT/clustering_XsLRTall__BRB0432lane2noumi_H3mm18_Dox.csv"
#filepath_BRBdef <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/deftable_BRB_noumi_new_190520_fin191205ver.txt"
#filepath_BRBdef <- "/home/guestA/o70578a/akuwakado/kuwakado/ChILSeq2/Komatsu_3T3_EGFP_H3mm18_Dox_chIl_0111NOVAseq/TSS_count/ChILAll_TSS_pm5kb_withATAC/deftable_BRB_noumi_new_190520_fin191205ver_20200625.txt"
#filepath_BRBChILATAC_def <- "/home/guestA/o70578a/akuwakado/kuwakado/ChILSeq2/Komatsu_3T3_EGFP_H3mm18_Dox_chIl_0111NOVAseq/TSS_count/ChILAll_TSS_pm5kb_withATAC/deftable_multicov_ChIL01100111_20200501_3T3_EGFP18_UI_DoxMinus_H3p3K27acK4Kme327me3_withATAC_withBRB.txt"
#filepath_BRBensemble <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/ensemble_list_asia.csv" #BRBの時のgene名リスト
#filepath_BRB_FC_all <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/LRT/all__BRB0432lane2noumi_H3mm18_Dox.csv" #BRB等のDEGのリスト
#filepath_BRB_2gun <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/2gun/BRB0432lane2noumi_H3mm18_Dox_results_fdr0p1__final191205.csv" #BRB等のDEGのリスト

filepath_BRBdef <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Last_Rserver_200811/deftable_BRB_noumi_new_190520_Last20200811ver.txt"

filepath_BRBcluster <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Last_Rserver_200811/LRT/DEG_fdr0p1__BRB0432lane2noumi_H3mm18_Dox_kmeans4__cluster_result.csv" #BRB等のDEGのリスト

filepath_BRBallgene <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Last_Rserver_200811/H3mm18KO_3T3_Dox_normCount_genename.csv" #BRB等のDEGのリスト
filepath_BRBzscore <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Last_Rserver_200811/H3mm18KO_3T3_Dox__zscore_type_all.csv"


##20200811 log2FC
filepath_BRB_FC_deseq <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Last_Rserver_200811/2gun/BRB0432lane2noumi_H3mm18_Dox_resultsall_fdr0p1__final191205_last200811.csv" #BRB等のDEGのリスト
filepath_BRB_normcount <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Last_Rserver_200811/BRB0432lane2noumi_H3mm18_Dox__normCount__final191205_last200811.csv"


#filepath_BRB_normcount <- "/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/BRB0432lane2noumi_H3mm18_Dox__normCount__final191205.csv"

#Final_Last_Rserver_200811

BRBのデータ (DEG,log2FCを抜き出す)

#--- DEGのリストの呼び出し --------#
cluster_BRBlist <- readr::read_csv(filepath_BRBcluster) %>% mutate(cluster=factor(cluster,c(1:cluster_num))) #BRB等のDEGのリスト
Parsed with column specification:
cols(
  ens_gene = col_character(),
  ext_gene = col_character(),
  biotype = col_character(),
  chr = col_character(),
  cluster = col_double(),
  baseMean = col_double(),
  log2FoldChange = col_double(),
  lfcSE = col_double(),
  stat = col_double(),
  pvalue = col_double(),
  padj = col_double()
)
#--- log2 FCのリストの呼び出し --------#
re_BRB_all <- readr::read_csv(filepath_BRB_FC_deseq)
Parsed with column specification:
cols(
  aspect = col_character(),
  ens_gene = col_character(),
  ext_gene = col_character(),
  biotype = col_character(),
  chr = col_character(),
  baseMean = col_double(),
  log2FoldChange = col_double(),
  lfcSE = col_double(),
  stat = col_double(),
  pvalue = col_double(),
  padj = col_double()
)
#--- BRBの全geneリストの呼び出し --------# 
all_BRBlist <- readr::read_csv(filepath_BRBallgene) #normcount
Parsed with column specification:
cols(
  .default = col_double(),
  ens_gene = col_character(),
  ext_gene = col_character(),
  biotype = col_character(),
  chr = col_character()
)
See spec(...) for full column specifications.
nrow(all_BRBlist)
[1] 21707
#----#
zscore_BRB <- readr::read_csv(filepath_BRBzscore)
Parsed with column specification:
cols(
  .default = col_double(),
  ens_gene = col_character(),
  ext_gene = col_character(),
  biotype = col_character(),
  chr = col_character()
)
See spec(...) for full column specifications.
nrow(zscore_BRB)
[1] 21707
#----#
def_BRB <- readr::read_tsv(filepath_BRBdef) %>% mutate(seq=factor(seq, c("BRB")))  %>% 
mutate(time1 = time, rep1=rep) %>% unite(time1,rep1,col="time_replicate")  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% mutate(type=factor(type,c("DoxPlus","DoxMinus"))) %>% mutate(rep=factor(rep, c("1", "2", "3", "4")))%>% mutate(time_replicate=factor(time_replicate,c("UI_1", "UI_2", "UI_3", "UI_4", "0h_1","0h_2","24h_1","24h_2","48h_1","48h_2","48h_3","48h_4")))
Parsed with column specification:
cols(
  file = col_character(),
  sample0 = col_character(),
  barcode = col_character(),
  growth = col_character(),
  sample = col_character(),
  group = col_character(),
  time = col_character(),
  type = col_character(),
  seq = col_character(),
  rep = col_double()
)
#----#
#FC_rank_all_BRBlist <- re_BRB_all %>% arrange(desc(abs(log2FoldChange))) %>% mutate(Rank=row_number()) #normcount
#nrow(FC_rank_all_BRBlist)
#print(FC_rank_all_BRBlist)

#%>% mutate(cluster=factor(cluster,c(1:cluster_num))) #BRB等のDEGのリスト


###--- DESeq2により計算したnormalized countのうち、BRB等のDEGのリストにあったものを書き出し ---###
#norm_table_select <- normalizedcount %>% filter(ens_gene %in% cluster_BRBlist$ens_gene) %>% full_join(cluster_BRBlist, ., by="ens_gene") #DEGリストのnormalized count
#readr::write_csv(norm_table_select, paste(".",folder_name, paste(RNAseq_cluster,"__normalizedcount__",folder_name,".csv",sep=""),sep="/")) #normalized count csvにgene名を付けた。
#------------------------------------------------------------------------------------------------# 
#----#
norm_BRB_def_original <- readr::read_csv(filepath_BRB_normcount)
Parsed with column specification:
cols(
  ens_gene = col_character(),
  sample = col_character(),
  normalized = col_double(),
  file = col_character(),
  sample0 = col_character(),
  barcode = col_character(),
  growth = col_character(),
  group = col_character(),
  time = col_character(),
  type = col_character(),
  seq = col_character(),
  rep = col_double(),
  count = col_double(),
  ext_gene = col_character(),
  biotype = col_character(),
  chr = col_character()
)
#norm_BRB <- norm_BRB_def_original %>% dplyr::rename(Type=type,rep=replicate,norm=normalized) %>% mutate(type=case_when(Type=="Doxminus"~"DoxMinus",Type=="Doxplus"~"DoxPlus"))  %>% mutate(seq="BRB") %>% 
#mutate(time1 = time, rep1=rep) %>% unite(time1,rep1,col="time_replicate")  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% mutate(type=factor(type,c("DoxPlus","DoxMinus"))) %>% mutate(rep=factor(rep, c("1", "2", "3", "4")))%>% mutate(time_replicate=factor(time_replicate,c("UI_1", "UI_2", "UI_3", "UI_4", "0h_1","0h_2","24h_1","24h_2","48h_1","48h_2","48h_3","48h_4")))

norm_BRB <- norm_BRB_def_original %>% dplyr::rename(norm=normalized) %>% mutate(seq="BRB") %>% 
mutate(time1 = time, rep1=rep) %>% unite(time1,rep1,col="time_replicate")  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% mutate(type=factor(type,c("DoxPlus","DoxMinus"))) %>% mutate(rep=factor(rep, c("1", "2", "3", "4")))%>% mutate(time_replicate=factor(time_replicate,c("UI_1", "UI_2", "UI_3", "UI_4", "0h_1","0h_2","24h_1","24h_2","48h_1","48h_2","48h_3","48h_4")))


# %>% mutate(group=case_when(Group=="Doxminus_Diff0h"~"BRB_0h_DoxMinus",Group=="Doxplus_Diff0h"~"BRB_0h_DoxPlus"))

print(norm_BRB)
#----#

#BRB_2gun <- readr::read_csv(filepath_BRB_2gun)

#"/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/LRT/clustering_XsLRTall__BRB0432lane2noumi_H3mm18_Dox.csv"
#--- DEGのリストに位置情報を加える
#bedfile_cluster <- bedfile %>% filter(ens_gene %in% cluster_BRBlist$ens_gene) %>% dplyr::select(ens_gene,TSS_region,gene_region,Strand) %>% full_join(cluster_BRBlist, ., by="ens_gene") #位置情報あり
# dplyr::select(ens_gene,TSS_region,gene_region,Strand)

#NormCountBRBmat <- readr::read_csv("/home/guestA/o70578a/akuwakado/kuwakado/BRBSeq/H3mm18_Dox_0432lane2/Final_Rserver_191203/H3mm18KO_3T3_Dox_normCount_genename.csv")

compare H3.3 cluster & BRB DEG cluster

list1 <- rrres_allH3p3 %>% filter(ens_gene %in% cluster_BRBlist$ens_gene) %>% group_by(cluster) %>% summarise(BRBcount=n(),genelist=paste(ext_gene,collapse=", "),IDlist=paste(ens_gene,collapse=", "))
`summarise()` ungrouping output (override with `.groups` argument)
#list2 <- rrres_H3p3clus2 %>% filter(ens_gene %in% cluster_BRBlist$ens_gene) %>% group_by(cluster) %>% summarise(BRBcount=n(),genelist=paste(ext_gene,collapse=", "),IDlist=paste(ens_gene,collapse=", "))

readr::write_csv(list1,"Compare_ChILATAC_cluster_vs_BRBDEGs.csv")
#readr::write_csv(list2,"Compare_ChILATAC_cluster2_vs_BRBDEGs.csv")

print(list1)

cluster1 <- cluster_BRBlist %>% filter(cluster=="1")
cluster2 <- cluster_BRBlist %>% filter(cluster=="2")
cluster3 <- cluster_BRBlist %>% filter(cluster=="3")
cluster4 <- cluster_BRBlist %>% filter(cluster=="4")


listclus <- rrres_allH3p3 %>% dplyr::select(ens_gene,ext_gene,cluster) %>% filter(ens_gene %in% cluster_BRBlist$ens_gene) %>% left_join(dplyr::select(cluster_BRBlist,ens_gene,cluster) %>% dplyr::rename(BRBclus=cluster)) %>% group_by(cluster,BRBclus) %>% summarise(count=n(),genelist=paste(ext_gene,collapse=", "),IDlist=paste(ens_gene,collapse=", "))
Joining, by = "ens_gene"
`summarise()` regrouping output by 'cluster' (override with `.groups` argument)
listclus2 <- listclus %>% dplyr::select(cluster,BRBclus,count) %>% mutate(BRBclus=paste("BRBcluster",BRBclus,sep="")) %>% spread(key=BRBclus,value=count, fill = 0)


readr::write_csv(listclus,"./Compare/Compare_ChILATAC_cluster_vs_BRBDEGs_summary.csv")
readr::write_csv(listclus2,"./Compare/Compare_ChILATAC_cluster_vs_BRBDEGs_summarycount.csv")

print(listclus)
print(listclus2)
NA
NA

#---#

H3p3BRBlistclus <- listclus2 %>%  mutate(H3p3cluster=paste(cluster,sep = ""))
#H3p3BRBlistclus <- listclus2 %>%  mutate(H3p3cluster=paste("H3p3cluster",cluster,sep = ""))

H3p3BRBlistclus_mat <- H3p3BRBlistclus %>% ungroup() %>% dplyr::select(-cluster,-H3p3cluster) %>% as.matrix()
rownames(H3p3BRBlistclus_mat) <- H3p3BRBlistclus$H3p3cluster

H3p3BRBlistclus_count <- H3p3BRBlistclus %>% ungroup() %>% dplyr::select(-cluster) %>% gather(key=sample,value=count,-H3p3cluster)

#---#

resultchisq <- chisq.test(H3p3BRBlistclus_mat)
 カイ自乗近似は不正確かもしれません 
resultchisq

    Pearson's Chi-squared test

data:  H3p3BRBlistclus_mat
X-squared = 37.639, df = 15, p-value = 0.00102
#resultchisq$residuals
#resultchisq$expected
resultchisq$expected %>% sum()
[1] 226
#residuals <- resultchisq$residuals %>% as.data.frame(.) %>% tibble::rownames_to_column("H3p3cluster") %>% gather(key=sample,value=value,-(H3p3cluster)) %>% mutate(H3p3cluster=factor(H3p3cluster,c("H3p3cluster6","H3p3cluster5","H3p3cluster4","H3p3cluster3","H3p3cluster2","H3p3cluster1")))

#H3p3BRBlistclus_count_residuals <- residuals %>% left_join(H3p3BRBlistclus_count)  %>% mutate(H3p3cluster=factor(H3p3cluster,c("H3p3cluster6","H3p3cluster5","H3p3cluster4","H3p3cluster3","H3p3cluster2","H3p3cluster1")))

residuals <- resultchisq$residuals %>% as.data.frame(.) %>% tibble::rownames_to_column("H3p3cluster") %>% gather(key=sample,value=value,-(H3p3cluster)) %>% mutate(H3p3cluster=factor(H3p3cluster,c("1","2","3","4","5","6")))  %>% mutate(BRBcluster=gsub("BRBcluster","",sample)) %>% mutate(BRBcluster=factor(BRBcluster,c("4","3","2","1"))) 

H3p3BRBlistclus_count_residuals <- residuals %>% left_join(H3p3BRBlistclus_count)
Joining, by = c("H3p3cluster", "sample")
#%>% mutate(H3p3cluster=factor(H3p3cluster,c("1","2","3","4","5","6")))

paste(resultchisq$method,"Residual",sep=": ")
[1] "Pearson's Chi-squared test: Residual"
chisq_plot <- H3p3BRBlistclus_count_residuals %>% ggplot(aes(x=H3p3cluster, y=BRBcluster, fill=value, label=count)) + geom_tile() + geom_text(aes(x=H3p3cluster, y=BRBcluster, label=as.character(count))) +  scale_fill_gradient2(low="blue", high="red", na.value="black", name="") + theme(axis.text.x  = element_text(angle = 90),title = element_text(size=2),legend.position = "top") + theme_minimal() + ylab("BRB DEG cluster") + xlab("H3.3 cluster")

chisq_plot

ggsave(file="./Compare/H3p3BRBlistclus.pdf", plot = chisq_plot, dpi = 100, width = 5, height = 3,limitsize = FALSE)


chisq_plot2 <- H3p3BRBlistclus_count_residuals %>% ggplot(aes(x=H3p3cluster, y=BRBcluster, fill=value, label=count)) + geom_tile() +  scale_fill_gradient2(low="blue", high="red", na.value="black", name="") + theme(axis.text.x  = element_text(angle = 90),title = element_text(size=2),legend.position = "top") + theme_minimal()  + ylab("BRB DEG cluster") + xlab("H3.3 cluster")

chisq_plot2

ggsave(file="./Compare/H3p3BRBlistclus_notitle.pdf", plot = chisq_plot2, dpi = 100, width = 5, height = 3,limitsize = FALSE)


H3p3BRBlistclus_count_residuals %>% readr::write_csv("./Compare/H3p3BRBlistclus.csv")

##——— リストを保存 ————-# #– 確認 –#

rrres_allH3p3 %>% filter(ens_gene %in% cluster_BRBlist$ens_gene) %>% left_join(cluster_BRBlist %>% dplyr::rename(BRBclus=cluster)) %>% dplyr::select(cluster)%>% group_by(cluster) %>% summarise(count=n())

rrres_allH3p3 %>% filter(ens_gene %in% cluster_BRBlist$ens_gene) %>% left_join(cluster_BRBlist %>% dplyr::rename(BRBclus=cluster)) %>% dplyr::select(BRBclus,cluster) %>% group_by(BRBclus,cluster) %>% summarise(count=n())

##————————————#


log2FCをまとめて計算する

H3p3 cluster3 のChIL normalized count

normalized count (BRB DEG) の deftable等 (発現が低いものはCut)

まず、BRBで遺伝子発現が十分大きいものに絞り込む(Cut off リストの作成)


Set_cutoff <- 10.0

## 各時刻の平均を計算し、normalized count > 10 を超えるものを抽出する。

#----- SKMとCTXのみ取り出す ---# 20191205
#norm_BRB_all <- norm_BRB %>% gather("sample", "normalized",-(ens_gene)) %>% inner_join(def, by = "sample")
#norm_BRB_all <- norm_BRB_all %>% filter(intact_CTX=="CTX"|intact_CTX=="SKM") %>% mutate(WT_KO=factor(WT_KO, c("H3mm18KO","WT"))) %>% mutate(Day=factor(Day, c("Day0","Day5","Day14"))) %>% mutate(intact_CTX=factor(intact_CTX, c("CTX","SKM")))

#notm_plotlist_cutoff <- norm_plotlist_all %>% annotate() %>% group_by(ens_gene, ext_gene, Day, intact_CTX) %>% summarize(groupMean=mean(normalized))  %>% ungroup() %>% dplyr::select(ens_gene, ext_gene) %>% unique()


norm_BRB_beforecutoff <- norm_BRB %>% group_by(ens_gene, ext_gene, seq, time) %>% summarize(groupMean=mean(norm))
`summarise()` regrouping output by 'ens_gene', 'ext_gene', 'seq' (override with `.groups` argument)
nrow(norm_BRB_beforecutoff)
[1] 86828
nrow(norm_BRB_beforecutoff %>% ungroup() %>% dplyr::select(ens_gene, ext_gene) %>% unique()) #この値をMAplotのx軸に使用
[1] 21707
print("--- cut off ---")
[1] "--- cut off ---"
norm_BRB_cutoff <- norm_BRB_beforecutoff %>% filter(groupMean > Set_cutoff) %>% ungroup()
nrow(norm_BRB_cutoff)
[1] 28442
norm_BRB_cutoff_list <-norm_BRB_cutoff %>% dplyr::select(ens_gene, ext_gene) %>% unique()
nrow(norm_BRB_cutoff_list)
[1] 8159
norm_BRB_beforecutoff %>% readr::write_csv("./log2FC/tables/Norm_BRB_groupMean.csv")
norm_BRB_cutoff  %>% readr::write_csv("log2FC/tables/Norm_BRB_groupMean_cutoff10.csv")
norm_BRB_cutoff_list  %>% readr::write_csv("log2FC/tables/Norm_BRB_groupMean_cutoff10_genelist.csv")

re_H3p3_FC_cutoff <- re_H3p3_all %>% mutate(seq="H3p3", time=gsub("group_H3p3_","",aspect)) %>% mutate(time=gsub("_Doxplus_vs_minus","",time)) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,  log2FoldChange,seq,time) %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene)

re_H3K4me3_FC_cutoff <- re_H3K4me3_all %>% mutate(seq="H3K4me3", time=gsub("group_H3K4me3_","",aspect)) %>% mutate(time=gsub("_Doxplus_vs_minus","",time)) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,  log2FoldChange,seq,time)  %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene)

re_H3K27ac_FC_cutoff <- re_H3K27ac_all %>% mutate(seq="H3K27ac", time=gsub("group_H3K27ac_","",aspect)) %>% mutate(time=gsub("_Doxplus_vs_minus","",time)) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,  log2FoldChange,seq,time)  %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene)

re_H3K27me3_FC_cutoff <- re_H3K27me3_all %>% mutate(seq="H3K27me3", time=gsub("group_H3K27me3_","",aspect)) %>% mutate(time=gsub("_Doxplus_vs_minus","",time)) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,  log2FoldChange,seq,time)  %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene)

re_ATAC_FC_cutoff <- re_ATAC_all %>% mutate(seq="ATAC", time=gsub("group_ATAC_","",aspect)) %>% mutate(time=gsub("_Doxplus_vs_minus","",time)) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,  log2FoldChange,seq,time)  %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene)

re_BRB_FC_cutoff <- re_BRB_all %>% mutate(seq="BRB", time=gsub("group_","",aspect)) %>% mutate(time=gsub("_Doxplus_vs_minus","",time)) %>% dplyr::select(ens_gene,ext_gene,biotype,chr,  log2FoldChange,seq,time)  %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene)


filename <- "./log2FC/tables/log2FC_H3p3_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/log2FC_H3p3_cutoff10.csv"
readr::write_csv(re_H3p3_FC_cutoff,filename)
nrow(re_H3p3_FC_cutoff)
[1] 32636
filename <- "./log2FC/tables/log2FC_H3K4me3_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/log2FC_H3K4me3_cutoff10.csv"
readr::write_csv(re_H3K4me3_FC_cutoff,filename)
nrow(re_H3K4me3_FC_cutoff)
[1] 32636
filename <- "./log2FC/tables/log2FC_H3K27ac_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/log2FC_H3K27ac_cutoff10.csv"
readr::write_csv(re_H3K27ac_FC_cutoff,filename)
nrow(re_H3K27ac_FC_cutoff)
[1] 32636
filename <- "./log2FC/tables/log2FC_H3K27me3_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/log2FC_H3K27me3_cutoff10.csv"
readr::write_csv(re_H3K27me3_FC_cutoff,filename)
nrow(re_H3K27me3_FC_cutoff)
[1] 32636
filename <- "./log2FC/tables/lo2gFC_ATAC_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/lo2gFC_ATAC_cutoff10.csv"
readr::write_csv(re_ATAC_FC_cutoff,filename)
nrow(re_ATAC_FC_cutoff)
[1] 16318
filename <- "./log2FC/tables/log2FC_BRB_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/log2FC_BRB_cutoff10.csv"
readr::write_csv(re_BRB_FC_cutoff,filename)
nrow(re_BRB_FC_cutoff)
[1] 32636
## 全て結合
re_all_FC_cutoff <- bind_rows(re_H3p3_FC_cutoff, re_H3K4me3_FC_cutoff) %>% bind_rows(re_H3K27ac_FC_cutoff) %>% bind_rows(re_H3K27me3_FC_cutoff) %>% bind_rows(re_ATAC_FC_cutoff) %>% bind_rows(re_BRB_FC_cutoff) %>% mutate(seq=factor(seq, c("H3p3", "H3K4me3","H3K27ac","H3K27me3","ATAC","BRB"))) %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) 

re_all_FC_cutoff

filename <- "./log2FC/tables/log2FC_ChILATACBRB_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/log2FC_ChILATACBRB_cutoff10.csv"
readr::write_csv(re_all_FC_cutoff,filename)
nrow(re_all_FC_cutoff)
[1] 179498

spread_all_FC_cutoff <- re_all_FC_cutoff %>% group_by(ens_gene, ext_gene, biotype, chr, time) %>% spread(key=seq,value=log2FoldChange)
nrow(spread_all_FC_cutoff)
[1] 32636
spread_all_FC_cutoff <- spread_all_FC_cutoff %>% left_join(dplyr::select(norm_BRB_cutoff, ens_gene, ext_gene, time, groupMean) %>% dplyr::rename(BRBgroupMean=groupMean))
Joining, by = c("ens_gene", "ext_gene", "time")
nrow(spread_all_FC_cutoff)
[1] 32636
filename <- "./log2FC/tables/Spread_log2FC_ChILATACBRB_cutoff10.csv"
print(filename)
[1] "./log2FC/tables/Spread_log2FC_ChILATACBRB_cutoff10.csv"
readr::write_csv(spread_all_FC_cutoff,filename)

spread_all_FC_cutoff_clus <- spread_all_FC_cutoff %>% left_join(dplyr::select(rrres_allH3p3,ens_gene,cluster)) %>% dplyr::rename(H3p3cluster=cluster) %>% left_join(dplyr::select(cluster_BRBlist,ens_gene,cluster)) %>% dplyr::rename(BRBDEGcluster=cluster)
Joining, by = "ens_gene"
Joining, by = "ens_gene"
filename <- "./log2FC/tables/Spread_log2FC_ChILATACBRB_cutoff10__withCluster.csv"
print(filename)
[1] "./log2FC/tables/Spread_log2FC_ChILATACBRB_cutoff10__withCluster.csv"
readr::write_csv(spread_all_FC_cutoff_clus,filename)
nrow(spread_all_FC_cutoff_clus)
[1] 32636
spread_all_FC_cutoff_clus %>% ungroup() %>% dplyr::select(ens_gene,H3p3cluster) %>% unique() %>% group_by(H3p3cluster) %>% summarize(H3p3_cutoff_count=n()) 
`summarise()` ungrouping output (override with `.groups` argument)
rrres_allH3p3  %>% group_by(cluster) %>% summarize(H3p3_geneAllcount=n())
`summarise()` ungrouping output (override with `.groups` argument)
f_gene_H3p3clus3 <- function(x) x %>% filter(H3p3cluster=="3")
f_gene_BRBclus3 <- function(x) x %>% filter(BRBDEGcluster=="3")
list_gene_qpcr <-  c("Acta1","Myh3","Ttn","Myog")

spread_all_FC_cutoff_H3p3clus3 <- spread_all_FC_cutoff_clus  %>% ungroup() %>% f_gene_H3p3clus3
nrow(spread_all_FC_cutoff_H3p3clus3)
[1] 13452
filename <- "./log2FC/tables/Spread_log2FC_ChILATACBRB_cutoff10__withCluster__H3p3clus3.csv"
print(filename)
[1] "./log2FC/tables/Spread_log2FC_ChILATACBRB_cutoff10__withCluster__H3p3clus3.csv"
readr::write_csv(spread_all_FC_cutoff_H3p3clus3,filename)


spread_all_FC_cutoff_H3p3clus3
spread_all_FC_cutoff_H3p3clus3 %>% f_gene_H3p3clus3 %>% f_gene_BRBclus3
spread_all_FC_cutoff_H3p3clus3 %>% f_gene_H3p3clus3 %>% f_gene_BRBclus3 %>% filter(ext_gene %in% list_gene_qpcr)

H3p3clus3cutoff <- spread_all_FC_cutoff_H3p3clus3 %>% ungroup() %>% dplyr::select(ens_gene) %>% unique() %>% nrow() 
H3p3clus3cutoff_brbclus3 <- spread_all_FC_cutoff_H3p3clus3 %>% f_gene_BRBclus3 %>% ungroup() %>% dplyr::select(ens_gene) %>% unique() %>% nrow()

nrow(z_H3p3clus3)
[1] 10775
H3p3clus3cutoff
[1] 3363
H3p3clus3cutoff_brbclus3
[1] 55

plot_all_FC_cutoff_H3p3clus3 <- spread_all_FC_cutoff_H3p3clus3 %>% dplyr::mutate(label_text = dplyr::case_when(ext_gene %in% list_gene_qpcr ~ ext_gene, TRUE ~ ""),shape = dplyr::case_when(ext_gene %in% list_gene_qpcr ~ "TRUE", TRUE ~ "FALSE"))

nrow(plot_all_FC_cutoff_H3p3clus3)
[1] 13452
plot_all_FC_cutoff_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(!is.na(BRBgroupMean)) # groupMean > 10のみ残す

nrow(plot_all_FC_cutoff_H3p3clus3)
[1] 11802
filename <- "./log2FC/tables/Plot_log2FC_ChILATACBRB_cutoff10__withCluster__H3p3clus3.csv"
print(filename)
[1] "./log2FC/tables/Plot_log2FC_ChILATACBRB_cutoff10__withCluster__H3p3clus3.csv"
readr::write_csv(plot_all_FC_cutoff_H3p3clus3,filename)

plot_all_FC_cutoff_H3p3clus3 %>% group_by(time) %>% summarise(count=n()) #図中の数
`summarise()` ungrouping output (override with `.groups` argument)
plot_all_FC_cutoff_H3p3clus3 %>% f_gene_BRBclus3 %>% group_by(time) %>% summarise(count=n()) #図中の数(BRB DEG cluster3のみ)
`summarise()` ungrouping output (override with `.groups` argument)

Calculate Correlation H3.3 etc. vs BRB (All & BRB DEG Cluster3)

正規分布ならピアソンだが、今回正規分布ではないのでスピアマンの順位相関係数 を使う


Time_list <- c("UI","0h","24h","48h")


Count_FC_cutoff_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% ungroup() %>% group_by(time) %>% summarise(Plot_genes=n()) #図中の数
`summarise()` ungrouping output (override with `.groups` argument)
#######
print("~~ H3p3_BRB ~~")
[1] "~~ H3p3_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clusterAll: H3p3_BRB --"))
  corr_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3$H3p3, corr_H3p3clus3$BRB, method="spearman")
  #print(tttttt)
  
  if (i == 1) { 
      cortest_result_s <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".") %>% mutate(time=Time_list[i],target="H3p3clus3All",Compare=paste("H3p3", "BRB",sep="_"))
  } 
  else {
      ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3All",Compare=paste("H3p3", "BRB",sep="_"))
      cortest_result_s <- bind_rows(cortest_result_s, ssssss)
  }
}
[1] "----- UI --- H3p3clusterAll: H3p3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 0h --- H3p3clusterAll: H3p3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 24h --- H3p3clusterAll: H3p3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 48h --- H3p3clusterAll: H3p3_BRB --"
 タイのため正確な p 値を計算することができません 
print("~~ H3K4me3_BRB ~~")
[1] "~~ H3K4me3_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clusterAll: H3K4me3_BRB --"))
  corr_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3$H3K4me3, corr_H3p3clus3$BRB, method="spearman")
  #print(tttttt)
  
  ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3All",Compare=paste("H3K4me3", "BRB",sep="_"))
  cortest_result_s <- bind_rows(cortest_result_s, ssssss)
}
[1] "----- UI --- H3p3clusterAll: H3K4me3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 0h --- H3p3clusterAll: H3K4me3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 24h --- H3p3clusterAll: H3K4me3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 48h --- H3p3clusterAll: H3K4me3_BRB --"
 タイのため正確な p 値を計算することができません 
print("~~ H3K27ac_BRB ~~")
[1] "~~ H3K27ac_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clusterAll: H3K27ac_BRB --"))
  corr_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3$H3K27ac, corr_H3p3clus3$BRB, method="spearman")
  #print(tttttt)
  

  ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3All",Compare=paste("H3K27ac", "BRB",sep="_"))
  cortest_result_s <- bind_rows(cortest_result_s, ssssss)
}
[1] "----- UI --- H3p3clusterAll: H3K27ac_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 0h --- H3p3clusterAll: H3K27ac_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 24h --- H3p3clusterAll: H3K27ac_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 48h --- H3p3clusterAll: H3K27ac_BRB --"
 タイのため正確な p 値を計算することができません 
print("~~ H3K27me3_BRB ~~")
[1] "~~ H3K27me3_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clusterAll: H3K27me3_BRB --"))
  corr_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3$H3K27me3, corr_H3p3clus3$BRB, method="spearman")
  #print(tttttt)
  

  ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3All",Compare=paste("H3K27me3", "BRB",sep="_"))
  cortest_result_s <- bind_rows(cortest_result_s, ssssss)
}
[1] "----- UI --- H3p3clusterAll: H3K27me3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 0h --- H3p3clusterAll: H3K27me3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 24h --- H3p3clusterAll: H3K27me3_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 48h --- H3p3clusterAll: H3K27me3_BRB --"
 タイのため正確な p 値を計算することができません 
print("~~ ATAC_BRB ~~")
[1] "~~ ATAC_BRB ~~"
for (i in 1:length(Time_list)) {

  if ((i == 1)|(i == 4)) { 
    print(paste("-----",Time_list[i], "--- H3p3clusterAll: ATAC_BRB --"))
    corr_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter((time==Time_list[i]))
    tttttt <- cor.test(corr_H3p3clus3$ATAC, corr_H3p3clus3$BRB, method="spearman")
    #print(tttttt)

    ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3All",Compare=paste("ATAC", "BRB",sep="_"))
    cortest_result_s <- bind_rows(cortest_result_s, ssssss)
  } 
}
[1] "----- UI --- H3p3clusterAll: ATAC_BRB --"
 タイのため正確な p 値を計算することができません 
[1] "----- 48h --- H3p3clusterAll: ATAC_BRB --"
 タイのため正確な p 値を計算することができません 
print("~~ H3p3_ATAC ~~")
[1] "~~ H3p3_ATAC ~~"
for (i in 1:length(Time_list)) {

  if ((i == 1)|(i == 4)) { 
    print(paste("-----",Time_list[i], "--- H3p3clusterAll: H3p3_ATAC --"))
    corr_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter((time==Time_list[i]))
    tttttt <- cor.test(corr_H3p3clus3$H3p3, corr_H3p3clus3$ATAC, method="spearman")
    #print(tttttt)

    ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3All",Compare=paste("H3p3", "ATAC",sep="_"))
    cortest_result_s <- bind_rows(cortest_result_s, ssssss)
  } 
}
[1] "----- UI --- H3p3clusterAll: H3p3_ATAC --"
 タイのため正確な p 値を計算することができません 
[1] "----- 48h --- H3p3clusterAll: H3p3_ATAC --"
 タイのため正確な p 値を計算することができません 
cortest_result_s_H3p3clus3All <- cortest_result_s %>% group_by(target,time,Compare) %>% spread(key="Cor_test",value=Value)  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% arrange(time)

cortest_result_s_H3p3clus3All <- cortest_result_s_H3p3clus3All %>% left_join(Count_FC_cutoff_H3p3clus3)
Joining, by = "time"
print(cortest_result_s_H3p3clus3All)

cortest_result_s_H3p3clus3All %>% readr::write_csv("./log2FC/tables/Cortest_result_spearman_H3p3clus3All.csv")

Time_list <- c("UI","0h","24h","48h")
Count_FC_cutoff_H3p3clus3_BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% f_gene_BRBclus3 %>% ungroup() %>% group_by(time) %>% summarise(Plot_genes=n()) #図中の数(BRB DEG cluster3のみ)
`summarise()` ungrouping output (override with `.groups` argument)
#######
print("~~ H3p3_BRB ~~")
[1] "~~ H3p3_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clus3BRBclus3: H3p3_BRB --"))
  corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3BRBclus3$H3p3, corr_H3p3clus3BRBclus3$BRB, method="spearman")
  #print(tttttt)
  
  if (i == 1) { 
      cortest_result_s <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".") %>% mutate(time=Time_list[i],target="H3p3clus3BRBclus3",Compare=paste("H3p3", "BRB",sep="_"))
  } 
  else {
      ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3BRBclus3",Compare=paste("H3p3", "BRB",sep="_"))
      cortest_result_s <- bind_rows(cortest_result_s, ssssss)
  }
}
[1] "----- UI --- H3p3clus3BRBclus3: H3p3_BRB --"
[1] "----- 0h --- H3p3clus3BRBclus3: H3p3_BRB --"
[1] "----- 24h --- H3p3clus3BRBclus3: H3p3_BRB --"
[1] "----- 48h --- H3p3clus3BRBclus3: H3p3_BRB --"
print("~~ H3K4me3_BRB ~~")
[1] "~~ H3K4me3_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clus3BRBclus3: H3K4me3_BRB --"))
  corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3BRBclus3$H3K4me3, corr_H3p3clus3BRBclus3$BRB, method="spearman")
  #print(tttttt)
  
  ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3BRBclus3",Compare=paste("H3K4me3", "BRB",sep="_"))
  cortest_result_s <- bind_rows(cortest_result_s, ssssss)
}
[1] "----- UI --- H3p3clus3BRBclus3: H3K4me3_BRB --"
[1] "----- 0h --- H3p3clus3BRBclus3: H3K4me3_BRB --"
[1] "----- 24h --- H3p3clus3BRBclus3: H3K4me3_BRB --"
[1] "----- 48h --- H3p3clus3BRBclus3: H3K4me3_BRB --"
print("~~ H3K27ac_BRB ~~")
[1] "~~ H3K27ac_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clus3BRBclus3: H3K27ac_BRB --"))
  corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3BRBclus3$H3K27ac, corr_H3p3clus3BRBclus3$BRB, method="spearman")
  #print(tttttt)
  

  ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3BRBclus3",Compare=paste("H3K27ac", "BRB",sep="_"))
  cortest_result_s <- bind_rows(cortest_result_s, ssssss)
}
[1] "----- UI --- H3p3clus3BRBclus3: H3K27ac_BRB --"
[1] "----- 0h --- H3p3clus3BRBclus3: H3K27ac_BRB --"
[1] "----- 24h --- H3p3clus3BRBclus3: H3K27ac_BRB --"
[1] "----- 48h --- H3p3clus3BRBclus3: H3K27ac_BRB --"
print("~~ H3K27me3_BRB ~~")
[1] "~~ H3K27me3_BRB ~~"
for (i in 1:length(Time_list)) {
  print(paste("-----",Time_list[i], "--- H3p3clus3BRBclus3: H3K27me3_BRB --"))
  corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% filter((time==Time_list[i]))
  tttttt <- cor.test(corr_H3p3clus3BRBclus3$H3K27me3, corr_H3p3clus3BRBclus3$BRB, method="spearman")
  #print(tttttt)
  

  ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3BRBclus3",Compare=paste("H3K27me3", "BRB",sep="_"))
  cortest_result_s <- bind_rows(cortest_result_s, ssssss)
}
[1] "----- UI --- H3p3clus3BRBclus3: H3K27me3_BRB --"
[1] "----- 0h --- H3p3clus3BRBclus3: H3K27me3_BRB --"
[1] "----- 24h --- H3p3clus3BRBclus3: H3K27me3_BRB --"
[1] "----- 48h --- H3p3clus3BRBclus3: H3K27me3_BRB --"
print("~~ ATAC_BRB ~~")
[1] "~~ ATAC_BRB ~~"
for (i in 1:length(Time_list)) {

  if ((i == 1)|(i == 4)) { 
    print(paste("-----",Time_list[i], "--- H3p3clus3BRBclus3: ATAC_BRB --"))
    corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% filter((time==Time_list[i]))
    tttttt <- cor.test(corr_H3p3clus3BRBclus3$ATAC, corr_H3p3clus3BRBclus3$BRB, method="spearman")
    #print(tttttt)

    ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3BRBclus3",Compare=paste("ATAC", "BRB",sep="_"))
    cortest_result_s <- bind_rows(cortest_result_s, ssssss)
  } 
}
[1] "----- UI --- H3p3clus3BRBclus3: ATAC_BRB --"
[1] "----- 48h --- H3p3clus3BRBclus3: ATAC_BRB --"
print("~~ H3p3_ATAC ~~")
[1] "~~ H3p3_ATAC ~~"
for (i in 1:length(Time_list)) {

  if ((i == 1)|(i == 4)) { 
    print(paste("-----",Time_list[i], "--- H3p3clus3BRBclus3: H3p3_ATAC --"))
    corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% filter((time==Time_list[i]))
    tttttt <- cor.test(corr_H3p3clus3BRBclus3$H3p3, corr_H3p3clus3BRBclus3$ATAC, method="spearman")
    #print(tttttt)

    ssssss <- unlist(tttttt)  %>% as.data.frame() %>% tibble::rownames_to_column("Cor_test")  %>% as_tibble() %>% dplyr::rename(Value=".")  %>% mutate(time=Time_list[i],target="H3p3clus3BRBclus3",Compare=paste("H3p3", "ATAC",sep="_"))
    cortest_result_s <- bind_rows(cortest_result_s, ssssss)
  } 
}
[1] "----- UI --- H3p3clus3BRBclus3: H3p3_ATAC --"
[1] "----- 48h --- H3p3clus3BRBclus3: H3p3_ATAC --"
cortest_result_s_H3p3clus3BRBclus3 <- cortest_result_s %>% group_by(target,time,Compare) %>% spread(key="Cor_test",value=Value)  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% arrange(time)

cortest_result_s_H3p3clus3BRBclus3 <- cortest_result_s_H3p3clus3BRBclus3 %>% left_join(Count_FC_cutoff_H3p3clus3_BRBclus3)
Joining, by = "time"
print(cortest_result_s_H3p3clus3BRBclus3)

cortest_result_s_H3p3clus3BRBclus3 %>% readr::write_csv("./log2FC/tables/Cortest_results_spearman_H3p3clus3BRBclus3.csv")
# All
rank_corr_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% group_by(time) %>% mutate(rank_H3p3=rank(H3p3), rank_H3K4me3=rank(H3K4me3),  rank_H3K27ac=rank(H3K27ac), rank_H3K27me3=rank(H3K27me3), rank_ATAC=rank(ATAC), rank_BRB=rank(BRB))

#H3p3clus3BRBclus3
rank_corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3") %>% group_by(time) %>% mutate(rank_H3p3=rank(H3p3), rank_H3K4me3=rank(H3K4me3),  rank_H3K27ac=rank(H3K27ac), rank_H3K27me3=rank(H3K27me3), rank_ATAC=rank(ATAC), rank_BRB=rank(BRB))



###
fcplot <- rank_corr_H3p3clus3BRBclus3  %>% ggplot(aes(y=rank_BRB, x=rank_H3p3))  + facet_wrap(~time,nrow=1, scales = "free") + 
  xlim(0, NA) + ylim(0, NA) + geom_point(alpha = 0.6, size=1.0)+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank())

#+ xlim(0,60) + ylim(0,60)


fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3p3_BRB"),aes(x=0,y=60,label=paste(sprintf("%4.3e", estimate.rho),"  (",Plot_genes,"  genes)", sep="")), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 2.0)


#+ stat_smooth()
#+ stat_smooth(method = "lm", colour = "black", size = 1)
#+  geom_smooth(method = lm, se = FALSE)


fcplot



#rank_corr_H3p3clus3BRBclus3 <- plot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% filter((time=="48h")) %>% mutate(rank_H3p3=rank(H3p3), rank_H3K4me3=rank(H3K4me3),  rank_H3K27ac=rank(H3K27ac), rank_H3K27me3=rank(H3K27me3), rank_ATAC=rank(ATAC), rank_BRB=rank(BRB))

#cor.test(rank_corr_H3p3clus3BRBclus3$rank_H3p3, rank_corr_H3p3clus3BRBclus3$rank_BRB)

### 並び替えのため

groups_BRB_arr <- c("BRB_UI_DoxMinus","BRB_UI_DoxPlus","BRB_0h_DoxMinus","BRB_0h_DoxPlus","BRB_24h_DoxMinus","BRB_24h_DoxPlus","BRB_48h_DoxMinus","BRB_48h_DoxPlus")
groups_ATAC_arr <- c("ATAC_UI_DoxMinus","ATAC_UI_DoxPlus","ATAC_48h_DoxMinus","ATAC_48h_DoxPlus")
groups_H3p3_arr <- c("H3p3_UI_DoxMinus","H3p3_UI_DoxPlus","H3p3_0h_DoxMinus","H3p3_0h_DoxPlus","H3p3_24h_DoxMinus","H3p3_24h_DoxPlus","H3p3_48h_DoxMinus","H3p3_48h_DoxPlus")
groups_H3K4me3_arr <- c("H3K4me3_UI_DoxMinus","H3K4me3_UI_DoxPlus","H3K4me3_0h_DoxMinus","H3K4me3_0h_DoxPlus","H3K4me3_24h_DoxMinus","H3K4me3_24h_DoxPlus","H3K4me3_48h_DoxMinus","H3K4me3_48h_DoxPlus")
groups_H3K27ac_arr <- c("H3K27ac_UI_DoxMinus","H3K27ac_UI_DoxPlus","H3K27ac_0h_DoxMinus","H3K27ac_0h_DoxPlus","H3K27ac_24h_DoxMinus","H3K27ac_24h_DoxPlus","H3K27ac_48h_DoxMinus","H3K27ac_48h_DoxPlus")
groups_H3K27me3_arr <- c("H3K27me3_UI_DoxMinus","H3K27me3_UI_DoxPlus","H3K27me3_0h_DoxMinus","H3K27me3_0h_DoxPlus","H3K27me3_24h_DoxMinus","H3K27me3_24h_DoxPlus","H3K27me3_48h_DoxMinus","H3K27me3_48h_DoxPlus")


groupt_BRB_arr <- c("BRB_DoxMinus","BRB_DoxPlus")
groupt_ATAC_arr <- c("ATAC_DoxMinus","ATAC_DoxPlus")
groupt_H3p3_arr <- c("H3p3_DoxMinus","H3p3_DoxPlus")
groupt_H3K4me3_arr <- c("H3K4me3_DoxMinus","H3K4me3_DoxPlus")
groupt_H3K27ac_arr <- c("H3K27ac_DoxMinus","H3K27ac_DoxPlus")
groupt_H3K27me3_arr <- c("H3K27me3_DoxMinus","H3K27me3_DoxPlus")


gggg_list2 <- c("ens_gene", "ext_gene", "time","BRBgroupMean", "H3p3cluster", "BRBDEGcluster", all_of(groupt_H3p3_arr),all_of(groupt_H3K4me3_arr),all_of(groupt_H3K27ac_arr),all_of(groupt_H3K27me3_arr),all_of(groupt_ATAC_arr),all_of(groupt_BRB_arr))

gggg_list1 <- c("ens_gene", "H3p3cluster", "BRBDEGcluster",all_of(groups_H3p3_arr),all_of(groups_H3K4me3_arr),all_of(groups_H3K27ac_arr),all_of(groups_H3K27me3_arr),all_of(groups_ATAC_arr),all_of(groups_BRB_arr))


## 全て結合


norm_chilatac_cutoff <- norm_plotlist_all  %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene) %>% dplyr::select(ens_gene,sample,group,time,type,seq,rep,normalized)
norm_brb_cutoff <- norm_BRB  %>% filter(ens_gene %in% norm_BRB_cutoff$ens_gene) %>% dplyr::select(ens_gene,sample,group,time,type,seq,rep,norm) %>% rename(normalized=norm)

## 全て結合
norm_plotlist_cutoff <- bind_rows(norm_chilatac_cutoff,norm_brb_cutoff)  %>% mutate(seq=factor(seq, c("H3p3", "H3K4me3","H3K27ac","H3K27me3","ATAC","BRB"))) %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) # ChIL & ATAC & BRB (cut off 全て)

norm_typemean_cutoff <- norm_plotlist_cutoff  %>% group_by(ens_gene,group,time,type,seq) %>% summarise(TypeMean=mean(normalized))  %>% mutate(seq_type=paste(seq,type,sep="_"))
`summarise()` regrouping output by 'ens_gene', 'group', 'time', 'type' (override with `.groups` argument)
spread_norm_typemean_cutoff <- norm_typemean_cutoff %>% ungroup() %>% dplyr::select(ens_gene,time,seq_type,TypeMean)  %>% mutate(seq_type=factor(seq_type, c("H3p3_DoxMinus","H3p3_DoxPlus", "H3K4me3_DoxMinus","H3K4me3_DoxPlus","H3K27ac_DoxMinus","H3K27ac_DoxPlus","H3K27me3_DoxMinus","H3K27me3_DoxPlus","ATAC_DoxMinus","ATAC_DoxPlus","BRB_DoxMinus","BRB_DoxPlus"))) %>% arrange(seq_type) %>% spread(key=seq_type,value=TypeMean)

spread_norm_typemean_cutoff <- spread_norm_typemean_cutoff %>% left_join(dplyr::select(norm_BRB_cutoff, ens_gene, ext_gene, time, groupMean) %>% dplyr::rename(BRBgroupMean=groupMean))
Joining, by = c("ens_gene", "time")
nrow(spread_norm_typemean_cutoff)
[1] 32636
spread_norm_typemean_cutoff_clus <- spread_norm_typemean_cutoff %>% left_join(dplyr::select(rrres_allH3p3,ens_gene,cluster)) %>% dplyr::rename(H3p3cluster=cluster) %>% left_join(dplyr::select(cluster_BRBlist,ens_gene,cluster)) %>% dplyr::rename(BRBDEGcluster=cluster)  %>% dplyr::select(all_of(gggg_list2))
Joining, by = "ens_gene"
Joining, by = "ens_gene"
nrow(spread_norm_typemean_cutoff_clus)
[1] 32636
#####

time_norm_typemean_cutoff <- norm_typemean_cutoff %>% ungroup()  %>% dplyr::select(ens_gene,group,TypeMean) %>% group_by(ens_gene) %>% spread(key=group,value=TypeMean)

nrow(time_norm_typemean_cutoff)
[1] 8159
time_norm_typemean_cutoff_clus <- time_norm_typemean_cutoff %>% left_join(dplyr::select(rrres_allH3p3,ens_gene,cluster)) %>% dplyr::rename(H3p3cluster=cluster) %>% left_join(dplyr::select(cluster_BRBlist,ens_gene,cluster)) %>% dplyr::rename(BRBDEGcluster=cluster) %>% dplyr::select(all_of(gggg_list1))
Joining, by = "ens_gene"
Joining, by = "ens_gene"
nrow(time_norm_typemean_cutoff_clus)
[1] 8159
#####

filename <- "./Correlation/tables/normTypeMean_All_cutoff10.csv"
print(filename)
[1] "./Correlation/tables/normTypeMean_All_cutoff10.csv"
readr::write_csv(spread_norm_typemean_cutoff_clus,filename)
head(spread_norm_typemean_cutoff_clus)
nrow(spread_norm_typemean_cutoff_clus)
[1] 32636
filename <- "./Correlation/tables/normTypeMean_All_cutoff10__timever.csv"
print(filename)
[1] "./Correlation/tables/normTypeMean_All_cutoff10__timever.csv"
readr::write_csv(time_norm_typemean_cutoff_clus,filename)
head(time_norm_typemean_cutoff_clus)
nrow(time_norm_typemean_cutoff_clus)
[1] 8159
#f_gene_H3p3clus3 <- function(x) x %>% filter(H3p3cluster=="3")
#f_gene_BRBclus3 <- function(x) x %>% filter(BRBDEGcluster=="3")
#list_gene_qpcr <-  c("Acta1","Myh3","Ttn","Myog")

corr_typemean_cutoff_H3p3clus3 <- time_norm_typemean_cutoff_clus   %>% ungroup() %>% f_gene_H3p3clus3
nrow(corr_typemean_cutoff_H3p3clus3)
[1] 3363
corr_typemean_cutoff_H3p3clus3BRBclus3 <- time_norm_typemean_cutoff_clus   %>% ungroup() %>% f_gene_H3p3clus3 %>% f_gene_BRBclus3
nrow(corr_typemean_cutoff_H3p3clus3BRBclus3)
[1] 55
####

corr_typemean_cutoff_H3p3clus3_filter <- spread_norm_typemean_cutoff_clus  %>% filter(!is.na(BRBgroupMean))  %>% ungroup() %>% f_gene_H3p3clus3
nrow(corr_typemean_cutoff_H3p3clus3_filter)
[1] 11802
corr_typemean_cutoff_H3p3clus3BRBclus3_filter <- spread_norm_typemean_cutoff_clus  %>% filter(!is.na(BRBgroupMean))  %>% ungroup() %>% f_gene_H3p3clus3 %>% f_gene_BRBclus3
nrow(corr_typemean_cutoff_H3p3clus3BRBclus3_filter)
[1] 190
corr_typemean_cutoff_H3p3clus3_filter %>% group_by(time) %>% summarise(count=n())
`summarise()` ungrouping output (override with `.groups` argument)
corr_typemean_cutoff_H3p3clus3BRBclus3_filter %>% group_by(time) %>% summarise(count=n())
`summarise()` ungrouping output (override with `.groups` argument)
#filename <- "./log2FC/tables/Spread_log2FC_ChILATACBRB_cutoff10__withCluster__H3p3clus3.csv"
#print(filename)
#readr::write_csv(spread_norm_typemean_cutoff_H3p3clus3,filename)


#spread_norm_typemean_cutoff_H3p3clus3
#spread_norm_typemean_cutoff_H3p3clus3 %>% f_gene_H3p3clus3 %>% f_gene_BRBclus3
#spread_norm_typemean_cutoff_H3p3clus3 %>% f_gene_H3p3clus3 %>% f_gene_BRBclus3 %>% filter(ext_gene %in% list_gene_qpcr)

#H3p3clus3cutoff <- spread_norm_typemean_cutoff_H3p3clus3 %>% ungroup() %>% dplyr::select(ens_gene) %>% unique() %>% nrow() 
#H3p3clus3cutoff_brbclus3 <- spread_norm_typemean_cutoff_H3p3clus3 %>% f_gene_BRBclus3 %>% ungroup() %>% dplyr::select(ens_gene) %>% unique() %>% nrow()

#nrow(z_H3p3clus3)
#H3p3clus3cutoff
#H3p3clus3cutoff_brbclus3

いずれかで BRB norm (group) > 10を満たすものでプロット


library(corrplot)

#### calculate correlation

print("Genes list")
[1] "Genes list"
nrow(corr_typemean_cutoff_H3p3clus3)
[1] 3363
nrow(corr_typemean_cutoff_H3p3clus3BRBclus3)
[1] 55
mydata.cor.All.alltime <- corr_typemean_cutoff_H3p3clus3 %>% ungroup() %>% dplyr::select(-"ens_gene", -"H3p3cluster", -"BRBDEGcluster") %>% cor(method = c("spearman"))
mydata.cor.BRBclus3.alltime <- corr_typemean_cutoff_H3p3clus3BRBclus3 %>% ungroup() %>% dplyr::select(-"ens_gene", -"H3p3cluster", -"BRBDEGcluster") %>% cor(method = c("spearman"))


cor_All_alltime <- as.data.frame(mydata.cor.All.alltime) %>% tibble::rownames_to_column("group") %>% as_tibble 
cor_BRBclus3_alltime <- as.data.frame(mydata.cor.BRBclus3.alltime) %>% tibble::rownames_to_column("group") %>% as_tibble 

####


title_1 <- paste("H3.3 Cluster3 & BRB DEG Cluster3:",nrow(corr_typemean_cutoff_H3p3clus3BRBclus3),"genes",sep=" ")
title_2 <- paste("H3.3 Cluster3:",nrow(corr_typemean_cutoff_H3p3clus3),"genes",sep=" ")


breaksList = seq(-1, 1, by = 0.05)
Color__a0 <- rev(brewer.pal(n = 11, name = "RdYlBu"))
Color__a <- colorRampPalette(Color__a0)(length(breaksList))


gaps_1 <- c(8,16,24,32,36)



pheatmap::pheatmap(mydata.cor.BRBclus3.alltime, main = title_1, scale = "none", color = Color__a,breaks = breaksList, border_color=NA)

pheatmap::pheatmap(mydata.cor.All.alltime, main = title_2, scale = "none", color = Color__a,breaks = breaksList, border_color=NA)


pheatmap::pheatmap(mydata.cor.BRBclus3.alltime, main = title_1, scale = "none", color = Color__a,breaks = breaksList, border_color=NA, cluster_rows = FALSE, cluster_cols = FALSE, gaps_col=gaps_1, gaps_row=gaps_1)

pheatmap::pheatmap(mydata.cor.All.alltime, main = title_2, scale = "none", color = Color__a,breaks = breaksList, border_color=NA, cluster_rows = FALSE, cluster_cols = FALSE, gaps_col=gaps_1, gaps_row=gaps_1)



corrplot(mydata.cor.BRBclus3.alltime, diag = FALSE, col = Color__a)

corrplot(mydata.cor.All.alltime, diag = FALSE, col = Color__a)



#####

filename <- "./Correlation/tables/Cortest_normTypeMean_spearman_H3p3clus3All_cutoff10__timever.csv"
print(filename)
[1] "./Correlation/tables/Cortest_normTypeMean_spearman_H3p3clus3All_cutoff10__timever.csv"
readr::write_csv(cor_All_alltime,filename)
print(cor_All_alltime)
nrow(cor_All_alltime)
[1] 44
filename <- "./Correlation/tables/Cortest_normTypeMean_spearman_H3p3clus3BRBclus3_cutoff10__timever.csv"
print(filename)
[1] "./Correlation/tables/Cortest_normTypeMean_spearman_H3p3clus3BRBclus3_cutoff10__timever.csv"
readr::write_csv(cor_BRBclus3_alltime,filename)
print(cor_BRBclus3_alltime)
nrow(cor_BRBclus3_alltime)
[1] 44
#corrplot(mydata.cor.BRBclus3.alltime, diag = FALSE, type = "upper", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.alltime, diag = FALSE, type = "lower", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.alltime, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.alltime, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))

## 表示リスト
gggg_plot_corlist <- c(all_of(groups_H3p3_arr),all_of(groups_H3K4me3_arr),all_of(groups_H3K27ac_arr),all_of(groups_BRB_arr))


cor_All_alltime_select <- cor_All_alltime %>% dplyr::select(group, all_of(gggg_plot_corlist)) %>% filter(group %in% gggg_plot_corlist)
mat_cor_All_alltime_select <- cor_All_alltime_select %>% dplyr::select(-group) %>% as.matrix()
rownames(mat_cor_All_alltime_select) <- cor_All_alltime_select$group


cor_BRBclus3_alltime_select <- cor_BRBclus3_alltime %>% dplyr::select(group, all_of(gggg_plot_corlist)) %>% filter(group %in% gggg_plot_corlist)
mat_cor_BRBclus3_alltime_select <- cor_BRBclus3_alltime_select %>% dplyr::select(-group) %>% as.matrix()
rownames(mat_cor_BRBclus3_alltime_select) <- cor_BRBclus3_alltime_select$group

gaps_2 <- c(8,16,24)

#### plot (select only)

#breaksList = seq(-1, 1, by = 0.05)
#Color__a0 <- rev(brewer.pal(n = 11, name = "RdYlBu"))
#Color__a <- colorRampPalette(Color__a0)(length(breaksList))

pheatmap::pheatmap(mat_cor_BRBclus3_alltime_select, main = title_1, scale = "none", color = Color__a,breaks = breaksList, border_color=NA)

pheatmap::pheatmap(mat_cor_All_alltime_select, main = title_2, scale = "none", color = Color__a,breaks = breaksList, border_color=NA)


pheatmap::pheatmap(mat_cor_BRBclus3_alltime_select, main = title_1, scale = "none", color = Color__a,breaks = breaksList, border_color=NA, cluster_rows = FALSE, cluster_cols = FALSE, gaps_col=gaps_2, gaps_row=gaps_2)

pheatmap::pheatmap(mat_cor_All_alltime_select, main = title_2, scale = "none", color = Color__a,breaks = breaksList, border_color=NA, cluster_rows = FALSE, cluster_cols = FALSE, gaps_col=gaps_2, gaps_row=gaps_2)



corrplot(mat_cor_BRBclus3_alltime_select, diag = FALSE, col = Color__a)

corrplot(mat_cor_All_alltime_select, diag = FALSE, col = Color__a)


groups_UI_arr <- c(
  "H3p3_UI_DoxMinus","H3p3_UI_DoxPlus",
  "H3K4me3_UI_DoxMinus","H3K4me3_UI_DoxPlus",
  "H3K27ac_UI_DoxMinus","H3K27ac_UI_DoxPlus",
  "H3K27me3_UI_DoxMinus","H3K27me3_UI_DoxPlus",
  "ATAC_UI_DoxMinus","ATAC_UI_DoxPlus",
  "BRB_UI_DoxMinus","BRB_UI_DoxPlus")


groups_0h_arr <- c(
  "H3p3_0h_DoxMinus","H3p3_0h_DoxPlus",
  "H3K4me3_0h_DoxMinus","H3K4me3_0h_DoxPlus",
  "H3K27ac_0h_DoxMinus","H3K27ac_0h_DoxPlus",
  "H3K27me3_0h_DoxMinus","H3K27me3_0h_DoxPlus",
  "BRB_0h_DoxMinus","BRB_0h_DoxPlus")

groups_24h_arr <- c(
  "H3p3_24h_DoxMinus","H3p3_24h_DoxPlus",
  "H3K4me3_24h_DoxMinus","H3K4me3_24h_DoxPlus",
  "H3K27ac_24h_DoxMinus","H3K27ac_24h_DoxPlus",
  "H3K27me3_24h_DoxMinus","H3K27me3_24h_DoxPlus",
  "BRB_24h_DoxMinus","BRB_24h_DoxPlus")
  
groups_48h_arr <- c(
  "H3p3_48h_DoxMinus","H3p3_48h_DoxPlus",
  "H3K4me3_48h_DoxMinus","H3K4me3_48h_DoxPlus",
  "H3K27ac_48h_DoxMinus","H3K27ac_48h_DoxPlus",
  "H3K27me3_48h_DoxMinus","H3K27me3_48h_DoxPlus",
  "ATAC_48h_DoxMinus","ATAC_48h_DoxPlus",
  "BRB_48h_DoxMinus","BRB_48h_DoxPlus")


groups_UI_arr_s <- c(
  "H3p3_UI_DoxMinus","H3p3_UI_DoxPlus",
  "H3K4me3_UI_DoxMinus","H3K4me3_UI_DoxPlus",
  "H3K27ac_UI_DoxMinus","H3K27ac_UI_DoxPlus",
  "BRB_UI_DoxMinus","BRB_UI_DoxPlus")


groups_0h_arr_s <- c(
  "H3p3_0h_DoxMinus","H3p3_0h_DoxPlus",
  "H3K4me3_0h_DoxMinus","H3K4me3_0h_DoxPlus",
  "H3K27ac_0h_DoxMinus","H3K27ac_0h_DoxPlus",
  "BRB_0h_DoxMinus","BRB_0h_DoxPlus")

groups_24h_arr_s <- c(
  "H3p3_24h_DoxMinus","H3p3_24h_DoxPlus",
  "H3K4me3_24h_DoxMinus","H3K4me3_24h_DoxPlus",
  "H3K27ac_24h_DoxMinus","H3K27ac_24h_DoxPlus",
  "BRB_24h_DoxMinus","BRB_24h_DoxPlus")
  
groups_48h_arr_s <- c(
  "H3p3_48h_DoxMinus","H3p3_48h_DoxPlus",
  "H3K4me3_48h_DoxMinus","H3K4me3_48h_DoxPlus",
  "H3K27ac_48h_DoxMinus","H3K27ac_48h_DoxPlus",
  "BRB_48h_DoxMinus","BRB_48h_DoxPlus")


## 表示リスト
gggg_plot_corlist_time <- c(all_of(groups_UI_arr_s),all_of(groups_0h_arr_s),all_of(groups_24h_arr_s),all_of(groups_48h_arr_s))


cor_All_alltime_select2 <- cor_All_alltime %>% dplyr::select(group, all_of(gggg_plot_corlist_time)) %>% filter(group %in% gggg_plot_corlist_time) %>% mutate(group=factor(group,gggg_plot_corlist_time)) %>% arrange(group)
mat_cor_All_alltime_select2 <- cor_All_alltime_select2 %>% dplyr::select(-group) %>% as.matrix()
rownames(mat_cor_All_alltime_select2) <- cor_All_alltime_select2$group


cor_BRBclus3_alltime_select2 <- cor_BRBclus3_alltime%>% dplyr::select(group, all_of(gggg_plot_corlist_time)) %>% filter(group %in% gggg_plot_corlist_time) %>% mutate(group=factor(group,gggg_plot_corlist_time)) %>% arrange(group)
mat_cor_BRBclus3_alltime_select2 <- cor_BRBclus3_alltime_select2 %>% dplyr::select(-group) %>% as.matrix()
rownames(mat_cor_BRBclus3_alltime_select2) <- cor_BRBclus3_alltime_select2$group

gaps_2 <- c(8,16,24)

#### plot (select only)

pheatmap::pheatmap(mat_cor_BRBclus3_alltime_select2, main = title_1, scale = "none", color = Color__a,breaks = breaksList, border_color=NA, cluster_rows = FALSE, cluster_cols = FALSE, gaps_col=gaps_2, gaps_row=gaps_2)

pheatmap::pheatmap(mat_cor_All_alltime_select2, main = title_2, scale = "none", color = Color__a,breaks = breaksList, border_color=NA, cluster_rows = FALSE, cluster_cols = FALSE, gaps_col=gaps_2, gaps_row=gaps_2)

NA
NA
NA
mydata.cor.BRBclus3.0h <- corr_typemean_cutoff_H3p3clus3BRBclus3_filter %>% ungroup() %>% filter(time=="0h")   %>% dplyr::select(BRB_DoxMinus, BRB_DoxPlus, H3p3_DoxMinus,H3p3_DoxPlus,H3K4me3_DoxMinus,H3K4me3_DoxPlus,H3K27ac_DoxMinus,H3K27ac_DoxPlus) %>% cor(method = c("spearman"))
mydata.cor.BRBclus3.24h <- corr_typemean_cutoff_H3p3clus3BRBclus3_filter %>% ungroup() %>% filter(time=="24h")  %>% dplyr::select(BRB_DoxMinus, BRB_DoxPlus, H3p3_DoxMinus,H3p3_DoxPlus,H3K4me3_DoxMinus,H3K4me3_DoxPlus,H3K27ac_DoxMinus,H3K27ac_DoxPlus) %>% cor(method = c("spearman"))
mydata.cor.BRBclus3.48h <- corr_typemean_cutoff_H3p3clus3BRBclus3_filter %>% ungroup()  %>% filter(time=="48h")  %>% dplyr::select(BRB_DoxMinus, BRB_DoxPlus, H3p3_DoxMinus,H3p3_DoxPlus,H3K4me3_DoxMinus,H3K4me3_DoxPlus,H3K27ac_DoxMinus,H3K27ac_DoxPlus) %>% cor(method = c("spearman"))

mydata.cor.All.UI <- corr_typemean_cutoff_H3p3clus3_filter %>% ungroup() %>% filter(time=="UI")  %>% dplyr::select(BRB_DoxMinus, BRB_DoxPlus, H3p3_DoxMinus,H3p3_DoxPlus,H3K4me3_DoxMinus,H3K4me3_DoxPlus,H3K27ac_DoxMinus,H3K27ac_DoxPlus) %>% cor(method = c("spearman"))
mydata.cor.All.0h <- corr_typemean_cutoff_H3p3clus3_filter %>% ungroup() %>% filter(time=="0h")   %>% dplyr::select(BRB_DoxMinus, BRB_DoxPlus, H3p3_DoxMinus,H3p3_DoxPlus,H3K4me3_DoxMinus,H3K4me3_DoxPlus,H3K27ac_DoxMinus,H3K27ac_DoxPlus) %>% cor(method = c("spearman"))
mydata.cor.All.24h <- corr_typemean_cutoff_H3p3clus3_filter %>% ungroup() %>% filter(time=="24h")  %>% dplyr::select(BRB_DoxMinus, BRB_DoxPlus, H3p3_DoxMinus,H3p3_DoxPlus,H3K4me3_DoxMinus,H3K4me3_DoxPlus,H3K27ac_DoxMinus,H3K27ac_DoxPlus) %>% cor(method = c("spearman"))
mydata.cor.All.48h <- corr_typemean_cutoff_H3p3clus3_filter %>% ungroup()  %>% filter(time=="48h") %>% dplyr::select(BRB_DoxMinus, BRB_DoxPlus, H3p3_DoxMinus,H3p3_DoxPlus,H3K4me3_DoxMinus,H3K4me3_DoxPlus,H3K27ac_DoxMinus,H3K27ac_DoxPlus) %>% cor(method = c("spearman"))


#corrplot(mydata.cor.BRBclus3.UI, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.0h, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.24h, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.48h, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))

#corrplot(mydata.cor.All.UI, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.0h, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.24h, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.48h, diag = FALSE, method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))

corrplot(mydata.cor.BRBclus3.UI, diag = FALSE, method = "color")

corrplot(mydata.cor.BRBclus3.0h, diag = FALSE, method = "color")

corrplot(mydata.cor.BRBclus3.24h, diag = FALSE, method = "color")

corrplot(mydata.cor.BRBclus3.48h, diag = FALSE, method = "color")


corrplot(mydata.cor.All.UI, diag = FALSE, method = "color")

corrplot(mydata.cor.All.0h, diag = FALSE, method = "color")

corrplot(mydata.cor.All.24h, diag = FALSE, method = "color")

corrplot(mydata.cor.All.48h, diag = FALSE, method = "color")


corrplot(mydata.cor.BRBclus3.UI, diag = FALSE)

corrplot(mydata.cor.BRBclus3.0h, diag = FALSE)

corrplot(mydata.cor.BRBclus3.24h, diag = FALSE)

corrplot(mydata.cor.BRBclus3.48h, diag = FALSE)


corrplot(mydata.cor.All.UI, diag = FALSE)

corrplot(mydata.cor.All.0h, diag = FALSE)

corrplot(mydata.cor.All.24h, diag = FALSE)

corrplot(mydata.cor.All.48h, diag = FALSE)


#corrplot(mydata.cor.BRBclus3.UI, diag = FALSE, method = "color", col = cm.colors(100))
#corrplot(mydata.cor.BRBclus3.0h, diag = FALSE, method = "color", col = cm.colors(100))
#corrplot(mydata.cor.BRBclus3.24h, diag = FALSE, method = "color", col = cm.colors(100))
#corrplot(mydata.cor.BRBclus3.48h, diag = FALSE, method = "color", col = cm.colors(100))

#corrplot(mydata.cor.All.UI, diag = FALSE, method = "color", col = cm.colors(100))
#corrplot(mydata.cor.All.0h, diag = FALSE, method = "color", col = cm.colors(100))
#corrplot(mydata.cor.All.24h, diag = FALSE, method = "color", col = cm.colors(100))
#corrplot(mydata.cor.All.48h, diag = FALSE, method = "color", col = cm.colors(100))

#corrplot.mixed(cor(mydata.cor), order="hclust", tl.col="black")


#pheatmap::pheatmap(mydata.cor.All.UI,color=viridis::viridis(256),scale = "none")
#pheatmap::pheatmap(mydata.cor.All.0h,color=viridis::viridis(256),scale = "none")
#pheatmap::pheatmap(mydata.cor.All.24h,color=viridis::viridis(256),scale = "none")
#pheatmap::pheatmap(mydata.cor.All.48h,color=viridis::viridis(256),scale = "none")

#pheatmap::pheatmap(mydata.cor.BRBclus3.UI,color=viridis::viridis(256),scale = "none")
#pheatmap::pheatmap(mydata.cor.BRBclus3.0h,color=viridis::viridis(256),scale = "none")
#pheatmap::pheatmap(mydata.cor.BRBclus3.24h,color=viridis::viridis(256),scale = "none")
#pheatmap::pheatmap(mydata.cor.BRBclus3.48h,color=viridis::viridis(256),scale = "none")

#corrplot(mydata.cor.BRBclus3.UI, diag = FALSE, type = "upper", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.0h, diag = FALSE, type = "upper", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.24h, diag = FALSE, type = "upper", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.48h, diag = FALSE, type = "upper", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))

#corrplot(mydata.cor.All.UI, diag = FALSE, type = "lower", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.0h, diag = FALSE, type = "lower", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.24h, diag = FALSE, type = "lower", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.48h, diag = FALSE, type = "lower", method = "color", col = rev(brewer.pal(n = 10, name = "RdBu")))


#corrplot(mydata.cor.BRBclus3.UI, diag = FALSE, type = "upper", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.0h, diag = FALSE, type = "upper", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.24h, diag = FALSE, type = "upper", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.BRBclus3.48h, diag = FALSE, type = "upper", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))

#corrplot(mydata.cor.All.UI, diag = FALSE, type = "lower", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.0h, diag = FALSE, type = "lower", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.24h, diag = FALSE, type = "lower", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))
#corrplot(mydata.cor.All.48h, diag = FALSE, type = "lower", method = "square", col = rev(brewer.pal(n = 10, name = "RdBu")))

#corrplot.mixed(mydata.cor.BRBclus3.UI, lower.col = "black")
#corrplot.mixed(mydata.cor.BRBclus3.0h, lower.col = "black")
#corrplot.mixed(mydata.cor.BRBclus3.24h, lower.col = "black")
#corrplot.mixed(mydata.cor.BRBclus3.48h, lower.col = "black")

#corrplot(mydata.cor,palette = "PuOr")

library(corrplot)
# = read.csv("https://wiki.q-researchsoftware.com/images/b/b9/Ownership.csv", header = TRUE, fileEncoding="latin1")
#mydata.cor = cor(mydata)
#mydata.cor = cor(mydata, method = c("spearman")
#corrplot(mydata.cor)

#mydata.cor.UI <- rank_corr_H3p3clus3BRBclus3 %>% filter(time=="UI") %>% dplyr::select(ens_gene,ext_gene,time,H3p3,H3K4me3,H3K27ac,BRB) %>% tidyr::gather(key="seq",value=FC,-ens_gene,-ext_gene,-time) %>% mutate(time_seq=paste(time,seq,sep="_")) %>% ungroup %>% dplyr::select(ens_gene,time_seq,FC) %>% tidyr::spread(key = time_seq,value=FC) %>% dplyr::select(-ens_gene) %>% cor(method = c("spearman"))

#mydata.cor.0h <- rank_corr_H3p3clus3BRBclus3 %>% filter(time=="0h") %>% dplyr::select(ens_gene,ext_gene,time,H3p3,H3K4me3,H3K27ac,BRB) %>% tidyr::gather(key="seq",value=FC,-ens_gene,-ext_gene,-time) %>% mutate(time_seq=paste(time,seq,sep="_")) %>% ungroup %>% dplyr::select(ens_gene,time_seq,FC) %>% tidyr::spread(key = time_seq,value=FC) %>% dplyr::select(-ens_gene) %>% cor(method = c("spearman"))

#mydata.cor.24h <- rank_corr_H3p3clus3BRBclus3 %>% filter(time=="24h") %>% dplyr::select(ens_gene,ext_gene,time,H3p3,H3K4me3,H3K27ac,BRB) %>% tidyr::gather(key="seq",value=FC,-ens_gene,-ext_gene,-time) %>% mutate(time_seq=paste(time,seq,sep="_")) %>% ungroup %>% dplyr::select(ens_gene,time_seq,FC) %>% tidyr::spread(key = time_seq,value=FC) %>% dplyr::select(-ens_gene) %>% cor(method = c("spearman"))

#mydata.cor.48h <- rank_corr_H3p3clus3BRBclus3 %>% filter(time=="48h") %>% dplyr::select(ens_gene,ext_gene,time,H3p3,H3K4me3,H3K27ac,BRB) %>% tidyr::gather(key="seq",value=FC,-ens_gene,-ext_gene,-time) %>% mutate(time_seq=paste(time,seq,sep="_")) %>% ungroup %>% dplyr::select(ens_gene,time_seq,FC) %>% tidyr::spread(key = time_seq,value=FC) %>% dplyr::select(-ens_gene) %>% cor(method = c("spearman"))

mydata.cor.BRBclus3.UI <- rank_corr_H3p3clus3BRBclus3 %>% ungroup() %>% filter(time=="UI") %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))
mydata.cor.BRBclus3.0h <- rank_corr_H3p3clus3BRBclus3 %>% ungroup() %>% filter(time=="0h")  %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))
mydata.cor.BRBclus3.24h <- rank_corr_H3p3clus3BRBclus3 %>% ungroup() %>% filter(time=="24h") %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))
mydata.cor.BRBclus3.48h <- rank_corr_H3p3clus3BRBclus3 %>% ungroup()  %>% filter(time=="48h") %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))

mydata.cor.All.UI <- rank_corr_H3p3clus3 %>% ungroup() %>% filter(time=="UI") %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))
mydata.cor.All.0h <- rank_corr_H3p3clus3 %>% ungroup() %>% filter(time=="0h")  %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))
mydata.cor.All.24h <- rank_corr_H3p3clus3 %>% ungroup() %>% filter(time=="24h") %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))
mydata.cor.All.48h <- rank_corr_H3p3clus3 %>% ungroup()  %>% filter(time=="48h") %>% dplyr::select(BRB, H3p3,H3K4me3,H3K27ac) %>% cor(method = c("spearman"))


#corrplot.mixed(cor(mydata.cor), order="hclust", tl.col="black")
corrplot(mydata.cor.BRBclus3.UI, diag = FALSE, type = "upper", col = rev(brewer.pal(n = 10, name = "RdBu")))
corrplot(mydata.cor.BRBclus3.0h, diag = FALSE, type = "upper", col = rev(brewer.pal(n = 10, name = "RdBu")))
corrplot(mydata.cor.BRBclus3.24h, diag = FALSE, type = "upper", col = rev(brewer.pal(n = 10, name = "RdBu")))
corrplot(mydata.cor.BRBclus3.48h, diag = FALSE, type = "upper", col = rev(brewer.pal(n = 10, name = "RdBu")))

corrplot(mydata.cor.All.UI, diag = FALSE, type = "lower", col = rev(brewer.pal(n = 10, name = "RdBu")))
corrplot(mydata.cor.All.0h, diag = FALSE, type = "lower", col = rev(brewer.pal(n = 10, name = "RdBu")))
corrplot(mydata.cor.All.24h, diag = FALSE, type = "lower", col = rev(brewer.pal(n = 10, name = "RdBu")))
corrplot(mydata.cor.All.48h, diag = FALSE, type = "lower", col = rev(brewer.pal(n = 10, name = "RdBu")))

#corrplot.mixed(mydata.cor.BRBclus3.UI, lower.col = "black")
#corrplot.mixed(mydata.cor.BRBclus3.0h, lower.col = "black")
#corrplot.mixed(mydata.cor.BRBclus3.24h, lower.col = "black")
#corrplot.mixed(mydata.cor.BRBclus3.48h, lower.col = "black")

#corrplot(mydata.cor,palette = "PuOr")

spearmanとranking=>peason の相関係数が合っているかを調べること


#%>% group_by(target,time,Compare)
#  group_by(aspect,gs_cat,gs_subcat) %>%
#  mutate(padj=p.adjust(pval,"BH")) %>% ungroup()
#Cortest_H3p3clus3All <- readr::read_csv("./log2FC/tables/Cortest_result_spearman_H3p3clus3All.csv") %>% mutate(text=paste(" All (",Plot_genes,") Cor: ",sprintf("%4.3e", estimate.cor),", p.val: ",sprintf("%4.3e", p.value),sep=""))   %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% arrange(time)
#Cortest_H3p3clus3BRBclus3 <- readr::read_csv("./log2FC/tables/Cortest_result_spearman_H3p3clus3BRBclus3.csv")  %>% mutate(text=paste("Clus3 (",Plot_genes,") Cor: ",sprintf("%4.3e", estimate.cor),", p.val: ",sprintf("%4.3e", p.value),sep=""))  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% arrange(time)


Cortest_H3p3clus3All <- readr::read_csv("./log2FC/tables/Cortest_result_spearman_H3p3clus3All.csv") %>% mutate(text=paste(" All (",Plot_genes,") Spearman Cor: ",sprintf("%4.3e", estimate.rho),", p.val: ",sprintf("%4.3e", p.value),sep=""))   %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% arrange(time)
Cortest_H3p3clus3BRBclus3 <- readr::read_csv("./log2FC/tables/Cortest_results_spearman_H3p3clus3BRBclus3.csv")  %>% mutate(text=paste("Clus3 (",Plot_genes,") Spearman Cor: ",sprintf("%4.3e", estimate.rho),", p.val: ",sprintf("%4.3e", p.value),sep=""))  %>% mutate(time=factor(time, c("UI", "0h","24h","48h"))) %>% arrange(time)

Cortest_H3p3clus3All %>% readr::write_csv("./log2FC/tables/Cortest_result_spearman_H3p3clus3All_forPlot.csv")
Cortest_H3p3clus3BRBclus3 %>% readr::write_csv("./log2FC/tables/Cortest_result_spearman_H3p3clus3BRBclus3_forPlot.csv")

Showplot_all_FC_cutoff_H3p3clus3 <- plot_all_FC_cutoff_H3p3clus3 %>% mutate(H3p3vsBRB=case_when(((abs(BRB)>2)|(abs(H3p3)>1.0)|is.na(H3p3))~"Not Shown",TRUE~"Shown"),H3K4me3vsBRB=case_when(((abs(BRB)>2)|(abs(H3K4me3)>1.5)|is.na(H3K4me3))~"Not Shown",TRUE~"Shown"),H3K27acvsBRB=case_when(((abs(BRB)>2)|(abs(H3K27ac)>1.0)|is.na(H3K27ac))~"Not Shown",TRUE~"Shown"),H3K27me3vsBRB=case_when(((abs(BRB)>2)|(abs(H3K27me3)>1.0)|is.na(H3K27me3))~"Not Shown",TRUE~"Shown"),ATACvsBRB=case_when(((abs(BRB)>2)|(abs(ATAC)>0.4)|is.na(ATAC))~"Not Shown",TRUE~"Shown"))

Show_H3p3vsBRB_H3p3clus3All <- Showplot_all_FC_cutoff_H3p3clus3 %>% ungroup %>% group_by(H3p3vsBRB,time) %>% summarize(count=n()) %>% rename(Plot=H3p3vsBRB) %>% mutate(Compare="H3p3_BRB")
Show_H3K4me3vsBRB_H3p3clus3All <- Showplot_all_FC_cutoff_H3p3clus3 %>% ungroup %>% group_by(H3K4me3vsBRB,time) %>% summarize(count=n()) %>% rename(Plot=H3K4me3vsBRB) %>% mutate(Compare="H3K4me3_BRB")
Show_H3K27acvsBRB_H3p3clus3All <- Showplot_all_FC_cutoff_H3p3clus3 %>% ungroup %>% group_by(H3K27acvsBRB,time) %>% summarize(count=n()) %>% rename(Plot=H3K27acvsBRB) %>% mutate(Compare="H3K27ac_BRB")
Show_H3K27me3vsBRB_H3p3clus3All <- Showplot_all_FC_cutoff_H3p3clus3 %>% ungroup %>% group_by(H3K27me3vsBRB,time) %>% summarize(count=n()) %>% rename(Plot=H3K27me3vsBRB)%>% mutate(Compare="H3K27me3_BRB")
Show_ATACvsBRB_H3p3clus3All <- Showplot_all_FC_cutoff_H3p3clus3 %>% ungroup %>% group_by(ATACvsBRB,time) %>% summarize(count=n()) %>% rename(Plot=ATACvsBRB)%>% mutate(Compare="ATAC_BRB")


Show__vsBRB_H3p3clus3All <- bind_rows(Show_H3p3vsBRB_H3p3clus3All,Show_H3K4me3vsBRB_H3p3clus3All) %>% bind_rows(Show_H3K27acvsBRB_H3p3clus3All) %>% bind_rows(Show_H3K27me3vsBRB_H3p3clus3All) %>% bind_rows(Show_ATACvsBRB_H3p3clus3All) %>% mutate(target="H3p3clus3All")  %>% mutate(Count=case_when(Plot=="Not Shown"~paste("(",count,")",sep=""),TRUE~as.character(count))) %>% mutate(Plot=factor(Plot, c("Shown","Not Shown"))) %>% arrange(Compare,time,Plot)


Show_H3p3vsBRB_H3p3clus3BRBclus3 <- Showplot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3") %>% ungroup %>% group_by(H3p3vsBRB,time) %>% summarize(count=n(),gene=paste(ext_gene,collapse = ",")) %>% rename(Plot=H3p3vsBRB) %>% mutate(Compare="H3p3_BRB")
Show_H3K4me3vsBRB_H3p3clus3BRBclus3 <- Showplot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% ungroup %>% group_by(H3K4me3vsBRB,time) %>% summarize(count=n(),gene=paste(ext_gene,collapse = ",")) %>% rename(Plot=H3K4me3vsBRB) %>% mutate(Compare="H3K4me3_BRB")
Show_H3K27acvsBRB_H3p3clus3BRBclus3 <- Showplot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% ungroup %>% group_by(H3K27acvsBRB,time) %>% summarize(count=n(),gene=paste(ext_gene,collapse = ",")) %>% rename(Plot=H3K27acvsBRB) %>% mutate(Compare="H3K27ac_BRB")
Show_H3K27me3vsBRB_H3p3clus3BRBclus3 <- Showplot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% ungroup %>% group_by(H3K27me3vsBRB,time) %>% summarize(count=n(),gene=paste(ext_gene,collapse = ",")) %>% rename(Plot=H3K27me3vsBRB) %>% mutate(Compare="H3K27me3_BRB")
Show_ATACvsBRB_H3p3clus3BRBclus3 <- Showplot_all_FC_cutoff_H3p3clus3 %>% filter(BRBDEGcluster=="3")%>% ungroup %>% group_by(ATACvsBRB,time) %>% summarize(count=n(),gene=paste(ext_gene,collapse = ",")) %>% rename(Plot=ATACvsBRB) %>% mutate(Compare="ATAC_BRB")

Show__vsBRB_H3p3clus3BRBclus3 <- bind_rows(Show_H3p3vsBRB_H3p3clus3BRBclus3,Show_H3K4me3vsBRB_H3p3clus3BRBclus3) %>% bind_rows(Show_H3K27acvsBRB_H3p3clus3BRBclus3) %>% bind_rows(Show_H3K27me3vsBRB_H3p3clus3BRBclus3) %>% bind_rows(Show_ATACvsBRB_H3p3clus3BRBclus3)  %>% mutate(target="H3p3clus3BRBclus3")  %>% mutate(Count=case_when(Plot=="Not Shown"~paste("(",count,")",sep=""),TRUE~as.character(count))) %>% mutate(Plot=factor(Plot, c("Shown","Not Shown"))) %>% arrange(Compare,time,Plot)


####
Show__vsBRB_H3p3clus3All
Show__vsBRB_H3p3clus3BRBclus3
Show__vsBRB_H3p3clus3BRBclus3 %>% filter(Plot=="Not Shown")

Show__vsBRB_H3p3clus3All %>% readr::write_csv("./log2FC/tables/PLotshow_H3p3clus3All.csv")
Show__vsBRB_H3p3clus3BRBclus3 %>% readr::write_csv("./log2FC/tables/PLotshow_H3p3clus3BRBclus3.csv")

summa__vsBRB_H3p3clus3All <- Show__vsBRB_H3p3clus3All %>% ungroup() %>% group_by(target, time, Compare) %>% summarize(Show=paste(Count,collapse = " "))
summa__vsBRB_H3p3clus3BRBclus3 <- Show__vsBRB_H3p3clus3BRBclus3 %>% ungroup() %>% group_by(target, time, Compare) %>% summarize(Show=paste(Count,collapse = " "))

summa__vsBRB_H3p3clus3All %>% readr::write_csv("./log2FC/tables/PLotshow_H3p3clus3All_summary.csv")
summa__vsBRB_H3p3clus3BRBclus3 %>% readr::write_csv("./log2FC/tables/PLotshow_H3p3clus3BRBclus3_summary.csv")


summa__vsBRB_H3p3clus3_ALL_BRBclus3 <- bind_rows(summa__vsBRB_H3p3clus3All,summa__vsBRB_H3p3clus3BRBclus3) %>% mutate(target=factor(target, c("H3p3clus3All","H3p3clus3BRBclus3"))) %>% arrange(Compare,time,target) %>% mutate(clus=gsub("H3p3clus3","",target)) %>% ungroup() %>% group_by(time,Compare) %>% summarize(show=paste(Show,collapse = " / "),Cluster=paste(clus,collapse = " / "))


summa__vsBRB_H3p3clus3_ALL_BRBclus3 %>% readr::write_csv("./log2FC/tables/PLotshow_H3p3clus3_All_and_BRBclus3_summary.csv")

summa__vsBRB_H3p3clus3_ALL_BRBclus3

#density_color_low <- "#ECE038"
density_color_low <- "#FFFFFF"

#density_color_low <- "#ECE038"
density_color_low <- "#FFFFFF"
#density_color_high <- "#377EB8"
density_color_high <- "blue"
#density_color_low <- #FFFFFF"
#density_color_mid <- "yellow"
#density_color_high <- "red"

binsize <- 7


pppplottitle <- paste("log2 FC (Dox + vs -)\nBRB normalized count (Time, avg) > ",Set_cutoff,"\n H3.3 clus3: ",nrow(z_H3p3clus3)," genes\n Plot: ",H3p3clus3cutoff," genes\n BRB clus3:  ",H3p3clus3cutoff_brbclus3," genes",sep="")


###
fcplot <-plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3p3))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + stat_ellipse(type = "norm",color=density_color_high,size=0.2) + stat_ellipse(type = "norm",color="#000000",data=f_gene_BRBclus3,size=0.2) + geom_point(aes(y=BRB, x=H3p3),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + xlab("H3.3") + ggtitle(pppplottitle)+ xlim(-1.0, 1.0) + ylim(-2.0, 2.0)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_nolabel_H3p3clus3_cutoff__H3p3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)


ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_H3p3clus3_cutoff__H3p3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)


fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3p3_BRB"),aes(x=-1.0,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3p3_BRB"),aes(x=-1.0,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3p3_BRB"),aes(x=-1.0,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_withcorr_H3p3clus3_cutoff__H3p3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3K4me3))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + stat_ellipse(type = "norm",color=density_color_high,size=0.2) + stat_ellipse(type = "norm",color="#000000",data=f_gene_BRBclus3,size=0.2) + geom_point(aes(y=BRB, x=H3K4me3),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + ggtitle(pppplottitle)+ xlim(-1.5, 1.5) + ylim(-2.0, 2.0)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_nolabel_H3p3clus3_cutoff__H3K4me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)


ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_H3p3clus3_cutoff__H3K4me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3K4me3_BRB"),aes(x=-1.5,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3K4me3_BRB"),aes(x=-1.5,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3K4me3_BRB"),aes(x=-1.5,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_withcorr_H3p3clus3_cutoff__H3K4me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3K27ac))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + stat_ellipse(type = "norm",color=density_color_high,size=0.2) + stat_ellipse(type = "norm",color="#000000",data=f_gene_BRBclus3,size=0.2) + geom_point(aes(y=BRB, x=H3K27ac),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + ggtitle(pppplottitle)+ xlim(-1.0, 1.0) + ylim(-2.0, 2.0)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_nolabel_H3p3clus3_cutoff__H3K27acvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)


ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_H3p3clus3_cutoff__H3K27acvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3K27ac_BRB"),aes(x=-1.0,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3K27ac_BRB"),aes(x=-1.0,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3K27ac_BRB"),aes(x=-1.0,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_withcorr_H3p3clus3_cutoff__H3K27acvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3K27me3))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + stat_ellipse(type = "norm",color=density_color_high,size=0.2) + stat_ellipse(type = "norm",color="#000000",data=f_gene_BRBclus3,size=0.2) + geom_point(aes(y=BRB, x=H3K27me3),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + ggtitle(pppplottitle)+ xlim(-1.0, 1.0) + ylim(-2.0, 2.0)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_nolabel_H3p3clus3_cutoff__H3K27me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)


fcplot <- fcplot  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)


ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_H3p3clus3_cutoff__H3K27me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3K27me3_BRB"),aes(x=-1.0,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3K27me3_BRB"),aes(x=-1.0,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3K27me3_BRB"),aes(x=-1.0,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_withcorr_H3p3clus3_cutoff__H3K27me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3 %>% ggplot(aes(y=BRB, x=ATAC))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + stat_ellipse(type = "norm",color=density_color_high,size=0.2) + stat_ellipse(type = "norm",color="#000000",data=f_gene_BRBclus3,size=0.2) + geom_point(aes(y=BRB, x=ATAC),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + ggtitle(pppplottitle)+ xlim(-0.4, 0.4) + ylim(-2.0, 2.0)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_nolabel_H3p3clus3_cutoff__ATACvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)


fcplot <- fcplot  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)


ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_H3p3clus3_cutoff__ATACvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)


fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="ATAC_BRB"),aes(x=-0.4,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="ATAC_BRB"),aes(x=-0.4,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="ATAC_BRB"),aes(x=-0.4,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/ellipse/log2FC_ellipse_withcorr_H3p3clus3_cutoff__ATACvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

For Check


#density_color_low <- "#ECE038"
density_color_low <- "#FFFFFF"
#density_color_high <- "#377EB8"
density_color_high <- "blue"
#density_color_low <- #FFFFFF"
#density_color_mid <- "yellow"
#density_color_high <- "red"

binsize <- 7


pppplottitle <- paste("log2 FC (Dox + vs -)\nBRB normalized count (Time, avg) > ",Set_cutoff,"\n H3.3 clus3: ",nrow(z_H3p3clus3)," genes\n Plot: ",H3p3clus3cutoff," genes\n BRB clus3:  ",H3p3clus3cutoff_brbclus3," genes",sep="")


###
fcplot <-plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3p3))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density2d(aes(color=BRBDEGcluster),data=f_gene_BRBclus3,size=0.1,alpha = 0.5, bins=binsize) + geom_point(aes(y=BRB, x=H3p3, color=BRBDEGcluster,shape=shape),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + scale_shape_manual(values=c(21, 19)) + xlab("H3.3") + ggtitle(pppplottitle)  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_nolimit_H3p3clus3_cutoff__H3p3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  + xlim(-1.0, 1.0) + ylim(-2.0, 2.0)

#fcplot
ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_H3p3clus3_cutoff__H3p3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3p3_BRB"),aes(x=-1.0,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3p3_BRB"),aes(x=-1.0,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3p3_BRB"),aes(x=-1.0,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_withcorr_H3p3clus3_cutoff__H3p3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3K4me3))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density2d(aes(color=BRBDEGcluster),data=f_gene_BRBclus3,size=0.1,alpha = 0.5, bins=binsize) + geom_point(aes(y=BRB, x=H3K4me3, color=BRBDEGcluster,shape=shape),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + scale_shape_manual(values=c(21, 19))  + ggtitle(pppplottitle)  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_nolimit_H3p3clus3_cutoff__H3K4me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  + xlim(-1.5, 1.5) + ylim(-2.0, 2.0)

#fcplot
ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_H3p3clus3_cutoff__H3K4me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3K4me3_BRB"),aes(x=-1.5,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3K4me3_BRB"),aes(x=-1.5,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8) +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3K4me3_BRB"),aes(x=-1.5,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_withcorr_H3p3clus3_cutoff__H3K4me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3K27ac))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density2d(aes(color=BRBDEGcluster),data=f_gene_BRBclus3,size=0.1,alpha = 0.5, bins=binsize) + geom_point(aes(y=BRB, x=H3K27ac, color=BRBDEGcluster,shape=shape),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank())  + scale_shape_manual(values=c(21, 19))  + ggtitle(pppplottitle) + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_nolimit_H3p3clus3_cutoff__H3K27acvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  + xlim(-1.0, 1.0) + ylim(-2.0, 2.0)

#fcplot
ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_H3p3clus3_cutoff__H3K27acvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3K27ac_BRB"),aes(x=-1.0,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3K27ac_BRB"),aes(x=-1.0,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3K27ac_BRB"),aes(x=-1.0,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_withcorr_H3p3clus3_cutoff__H3K27acvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(y=BRB, x=H3K27me3))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density2d(aes(color=BRBDEGcluster),data=f_gene_BRBclus3,size=0.1,alpha = 0.5, bins=binsize) + geom_point(aes(y=BRB, x=H3K27me3, color=BRBDEGcluster,shape=shape),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank())  + scale_shape_manual(values=c(21, 19))  + ggtitle(pppplottitle)  + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_nolimit_H3p3clus3_cutoff__H3K27me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot   + xlim(-1.0, 1.0) + ylim(-2.0, 2.0)

#fcplot
ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_H3p3clus3_cutoff__H3K27me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="H3K27me3_BRB"),aes(x=-1.0,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="H3K27me3_BRB"),aes(x=-1.0,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8) +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="H3K27me3_BRB"),aes(x=-1.0,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_withcorr_H3p3clus3_cutoff__H3K27me3vsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3 %>% ggplot(aes(y=BRB, x=ATAC))  + facet_wrap(~time,ncol=1)  + stat_density2d(aes(fill=..density..), geom = "raster",contour = FALSE) + scale_fill_gradient(low = density_color_low, high = density_color_high)  + geom_abline(intercept=0,slope=0,colour="#000000",size=0.2) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density2d(aes(color=BRBDEGcluster),data=f_gene_BRBclus3,size=0.1,alpha = 0.5, bins=binsize) + geom_point(aes(y=BRB, x=ATAC, color=BRBDEGcluster,shape=shape),alpha = 0.6, size=1.0, data=f_gene_BRBclus3)  + scale_color_manual(values = c("#000000"))+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=10),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + scale_shape_manual(values=c(21, 19))  + ggtitle(pppplottitle) + geom_text_repel(aes(label = label_text), segment.color = "#000000",segment.size = 0.1) 

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_nolimit_H3p3clus3_cutoff__ATACvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  + xlim(-0.4, 0.4) + ylim(-2.0, 2.0)

#fcplot
ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_H3p3clus3_cutoff__ATACvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot <- fcplot  +  geom_text_repel(data=filter(Cortest_H3p3clus3BRBclus3,Compare=="ATAC_BRB"),aes(x=-0.4,y=1.8,label=text), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)  +  geom_text_repel(data=filter(Cortest_H3p3clus3All,Compare=="ATAC_BRB"),aes(x=-0.4,y=2.0,label=text), color = density_color_high, segment.color = density_color_high,segment.size = 0.1,size = 1.8) +  geom_text_repel(data=filter(summa__vsBRB_H3p3clus3_ALL_BRBclus3,Compare=="ATAC_BRB"),aes(x=-0.4,y=1.6,label=show), color = "#000000", segment.color = "#000000",segment.size = 0.1,size = 1.8)

ggsave(plot=fcplot,file="./log2FC/For_Check/log2FC_Check_withcorr_H3p3clus3_cutoff__ATACvsBRB.pdf", width = 3.5, height = 11, dpi = 360, limitsize = FALSE)

fcplot

20200817追加


#density_color_low <- "#ECE038"
density_color_low <- "#FFFFFF"
#density_color_high <- "#377EB8"
density_color_high <- "blue"
#density_color_low <- #FFFFFF"
#density_color_mid <- "yellow"
#density_color_high <- "red"

binsize <- 7


pppplottitle <- paste("log2 FC (Dox + vs -)\nBRB normalized count (Time, avg) > ",Set_cutoff,"\n H3.3 clus3: ",nrow(z_H3p3clus3)," genes\n Plot: ",H3p3clus3cutoff," genes\n BRB clus3:  ",H3p3clus3cutoff_brbclus3," genes",sep="")

###
fcplot <-plot_all_FC_cutoff_H3p3clus3 %>% ggplot(aes(x=BRB))  + facet_wrap(~time,ncol=1) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density(fill=density_color_high,color=density_color_high,alpha=0.5) + geom_density(fill="#000000",color="#000000",data=f_gene_BRBclus3,alpha=0.5) +theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=8),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank())+ xlim(-2.0, 2.0)

ggsave(plot=fcplot,file="./log2FC/histlog2FC__H3p3clus3_cutoff__BRB.pdf", width = 3.5, height = 3.5, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <-plot_all_FC_cutoff_H3p3clus3 %>% ggplot(aes(x=H3p3))  + facet_wrap(~time,ncol=1) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density(fill=density_color_high,color=density_color_high,alpha=0.5) + geom_density(fill="#000000",color="#000000",data=f_gene_BRBclus3,alpha=0.5) +theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=8),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + xlab("H3.3")+ xlim(-1.0, 1.0)

ggsave(plot=fcplot,file="./log2FC/histlog2FC__H3p3clus3_cutoff__H3p3.pdf", width = 3.5, height = 3.5, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3   %>% ggplot(aes(x=H3K4me3))  + facet_wrap(~time,ncol=1) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density(fill=density_color_high,color=density_color_high,alpha=0.5) + geom_density(fill="#000000",color="#000000",data=f_gene_BRBclus3,alpha=0.5) +theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=8),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank())+ xlim(-1.5, 1.5)

ggsave(plot=fcplot,file="./log2FC/histlog2FC__H3p3clus3_cutoff__H3K4me3.pdf", width = 3.5, height = 3.5, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3   %>% ggplot(aes(x=H3K27ac))  + facet_wrap(~time,ncol=1) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density(fill=density_color_high,color=density_color_high,alpha=0.5) + geom_density(fill="#000000",color="#000000",data=f_gene_BRBclus3,alpha=0.5) +theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=8),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + xlim(-1.0, 1.0)

ggsave(plot=fcplot,file="./log2FC/histlog2FC__H3p3clus3_cutoff__H3K27ac.pdf", width = 3.5, height = 3.5, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3   %>% ggplot(aes(x=H3K27me3))  + facet_wrap(~time,ncol=1) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density(fill=density_color_high,color=density_color_high,alpha=0.5) + geom_density(fill="#000000",color="#000000",data=f_gene_BRBclus3,alpha=0.5) +theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=8),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + xlim(-1.0, 1.0)

ggsave(plot=fcplot,file="./log2FC/histlog2FC__H3p3clus3_cutoff__H3K27me3.pdf", width = 3.5, height = 3.5, dpi = 360, limitsize = FALSE)

fcplot

###
fcplot <- plot_all_FC_cutoff_H3p3clus3  %>% ggplot(aes(x=ATAC))  + facet_wrap(~time,ncol=1) + geom_vline(xintercept = 0,colour="#000000",size=0.2) + geom_density(fill=density_color_high,color=density_color_high,alpha=0.5) + geom_density(fill="#000000",color="#000000",data=f_gene_BRBclus3,alpha=0.5)+theme_bw() + theme(axis.title = element_text(size=15),axis.text = element_text(size=8),axis.text.x = element_text(hjust = 0.5,vjust=1.0), legend.position = "right", strip.text=element_text(size=15),strip.background = element_blank(),title = element_text(size=8),panel.grid=element_blank()) + xlim(-0.4, 0.4)

ggsave(plot=fcplot,file="./log2FC/histlog2FC__H3p3clus3_cutoff__ATAC.pdf", width = 3.5, height = 3.5, dpi = 360, limitsize = FALSE)


fcplot

クラスタリング (H3.3 cluster) の結果をGO

2020.4.21, 7.17修正 ver

#20200421修正 ver
#20191206修正 ver

#z_heat_label_order_cluster6 <- z_heat_label_order_cluster %>% dplyr::select(ext_gene,heatmap_order,No,cluster_6) %>% mutate(heatmap_order=as.integer(heatmap_order),No=as.integer(No),cluster_6=as.integer(cluster_6))%>% arrange(heatmap_order) %>% left_join( dplyr::select(z_timedeg_s,ens_gene,ext_gene,biotype,chr))
#_____________#

## z_heat_label_order_cluster にクラスター番号が入っている

table_degcluster <- rrres_allH3p3 %>% filter(!is.na(cluster)) %>% arrange(cluster, ens_gene) %>% unique() %>% filter(!is.na(ens_gene))
degclusgene <- table_degcluster %>% group_by(cluster) %>% summarise(size=n()) %>% mutate(cluster=row_number())

table_degcluster <- table_degcluster %>% left_join(degclusgene %>% dplyr::select(cluster)) %>% arrange(cluster,ens_gene)

degclusgene
##### FDR setting ######
gofdr <- 0.1

#cluster_num <- 6
cluster_num <- nrow(degclusgene)
# 20191206修正

library(clusterProfiler)
library(org.Mm.eg.db)

folder_path <- "./H3p3allcluster/clusterProfile/"

#-------------#
file_path <- paste(folder_path, "GO_newcluster_BPfdr0p1_generatio",sep="")
filename_csv <- file_path

file_path <- paste(folder_path, "GO_newcluster_BPfdr0p1_generatio_cluster",sep="")
filename_list <- file_path

print(filename_list)
print(filename_csv)

#例 filename_list <- "./LRT/clusterProfile/H3mm18KO_mouseCTX_BRB0438_day5_2gunfdr0p2_kmeans_BPfdr0p1_generatio_cluster"
#例 filename_csv <- "./LRT/clusterProfile/H3mm18KO_mouseCTX_BRB0438_day5_2gunfdr0p2_kemans_BPfdr0p1_generatio"
#-------------#

cluster_list <- as.list(NA) #初期化

for (i in 1:cluster_num) {
   pre_list <- as.list(NA)
   pre_list <- table_degcluster %>% filter(cluster==as.integer(i)) %>% dplyr::select(ens_gene) %>% as.list()
   names(pre_list) <- paste("ENSEMBL",as.character(i),sep="_")
 
   if (i == 1) { 
     cluster_list <- pre_list
   } 
   else cluster_list <- c(cluster_list, pre_list) 
}


for (i in 1:cluster_num) {
   print(paste(i, cluster_list[[i]] %>% tibble::enframe(name = NULL) %>% nrow(), sep=", "))
  
   pre_ego_BP <- enrichGO(gene = cluster_list[[i]],
                 OrgDb = "org.Mm.eg.db",
                 keyType = 'ENSEMBL',
                 ont = "BP",
                 pAdjustMethod = "BH",
                 pvalueCutoff  = gofdr, qvalueCutoff  = 1.0) 
   
   #20191211修正  pvalueCutoff  = fdr
   
   ## pvalue < qvalue < p.adjust ##
   # qvalueCutoff  = 0.3  qvalueCutoff  = 0.2 , qvalueCutoff  = 1.0

   #if (i == 1) { 
  #   table_ego_BP <- data.frame(pre_ego_BP) %>% mutate(cluster=as.integer(i))
  #   # リスト型からデータフレームへ変換
   #} 
   #else table_ego_BP <- table_ego_BP %>% bind_rows(data.frame(pre_ego_BP) %>% mutate(cluster=as.integer(i)))
                                                  
  if (i == 1) { 
     table_ego_BP <- data.frame(pre_ego_BP) %>% mutate(cluster=paste("cluster",as.character(i),sep=""))  # リスト型からデータフレームへ変換
   } 
   else table_ego_BP <- table_ego_BP %>% bind_rows(data.frame(pre_ego_BP) %>% mutate(cluster=paste("cluster",as.character(i),sep="")))
   
   #---- plot ---#
   BPplot <- dotplot(pre_ego_BP, showCategory=30, orderBy = "Count") #clusterProfile の機能で図を描く(191106修正) wrong orderBy parameter; set to default `orderBy = "x"`
   print(BPplot)
   ggsave(BPplot,file=paste(filename_list,as.character(i),".png",sep=""), width = 12, height = 12, dpi = 120)
   ggsave(BPplot,file=paste(filename_list,as.character(i),".pdf",sep=""), width = 12, height = 12, dpi = 120)
}

print(table_ego_BP %>% group_by(cluster) %>% summarize())

#------#
# データはtable_ego_BPに。

#------------------------------------------------------#
# テーブルを保存
# table_ego_BP_3t3_LRT2 <- table_ego_BP
#
table_ego_BP1 <- table_ego_BP %>% mutate(cluster=factor(cluster,c("cluster1","cluster2","cluster3","cluster4","cluster5","cluster6"))) %>% arrange(cluster,desc(Count)) #191106(200415)

#table_ego_BP1 <- table_ego_BP %>% arrange(cluster,desc(Count))  %>% left_join(dplyr::select(degclusgene, cluster)) #191106(200415)

readr::write_csv(table_ego_BP1,paste(filename_csv,".csv",sep=""))

print(table_ego_BP %>% group_by(cluster) %>% summarize(cluster_3t3Dox_num = dplyr::n()))

# 先のテーブルのgeneIDをgene nameに置換する。(20191025)

tablego <- table_ego_BP1 %>% mutate(gene_name=geneID) %>% dplyr::select(-(qvalue))

for (i in 1:nrow(table_degcluster)) {
  tablego <- tablego %>% mutate(gene_name=gsub(gene_name, pattern=table_degcluster$ens_gene[i], replacement=table_degcluster$ext_gene[i], ignore.case = TRUE))
}

#print(tablego)

#readr::write_csv(tablego,paste(filename_csv,"_genename.csv",sep=""))

#------------------------------------------------------#

readr::write_csv(tablego,paste(filename_csv,"_genename.csv",sep=""))


library(chromVAR)
library(motifmatchr)
library(SummarizedExperiment)
library(Matrix)
library(ggplot2)
library(BiocParallel)
library(BSgenome.Mmusculus.UCSC.mm10)

list_plotallFCcutoff_H3p3clus3 <- dplyr::select(plot_all_FC_cutoff_H3p3clus3, ens_gene, ext_gene, biotype, chr, H3p3cluster, BRBDEGcluster) %>% unique()

TSSregion_H3p3clus3 <-  matome0_s %>% ungroup %>% dplyr::select(TSSstart,TSSend,ens_gene,score,strand,TSS,Start,End,position) %>% filter(ens_gene %in% list_plotallFCcutoff_H3p3clus3$ens_gene) %>% ungroup() %>% left_join(list_plotallFCcutoff_H3p3clus3)
Joining, by = "ens_gene"
#TSSPM10kb_H3p3clus3 <- TSSregion_H3p3clus3 %>% mutate(TSS_M10kb=TSS-10000,TSS_P10kb=TSS+10000) %>% dplyr::select(chr,TSS_M10kb,TSS_P10kb,ens_gene,score,strand,TSS,  Start,    End, position, ext_gene, biotype, H3p3cluster, BRBDEGcluster)

TSSPM10kb_H3p3clus3 <- TSSregion_H3p3clus3 %>% dplyr::select(chr,TSS,ens_gene, ext_gene,biotype, score, strand, H3p3cluster, BRBDEGcluster) %>% mutate(start=TSS-10000,end=TSS+10000) %>% dplyr::select(chr,start,end,ens_gene, score, strand,TSS, ext_gene,biotype,  H3p3cluster, BRBDEGcluster) %>% filter(BRBDEGcluster=="3")


TSSPM10kb_H3p3clus3_GR <- makeGRangesFromDataFrame(TSSPM10kb_H3p3clus3, keep.extra.columns = TRUE)

seqlevelsStyle(TSSPM10kb_H3p3clus3_GR) <- "UCSC"

#####

peakfile <- "./Motif/TSSPM10kb_H3p3clus3.csv"
print(peakfile)
[1] "./Motif/TSSPM10kb_H3p3clus3.csv"
readr::write_csv(TSSPM10kb_H3p3clus3,peakfile)
head(TSSPM10kb_H3p3clus3)
nrow(TSSPM10kb_H3p3clus3)
[1] 55

def_bam_path <- "/home/guestA/o70578a/akuwakado/kuwakado/ChILSeq2/Komatsu_3T3_EGFP_H3mm18_Dox_chIl_0111NOVAseq/ChromVAR/ChromVAR_ChIL/H3K27ac_H3K27acpeak/deftable_ChromVAR_ChIL01100111_20200501_3T3_EGFP18_UI_DoxMinus_H3p3K27acK4Kme327me3.txt"

def_H3K27ac_bam <-  readr::read_tsv(file =def_bam_path) %>% filter(seq=="H3K27ac")
Parsed with column specification:
cols(
  file = col_character(),
  multicov_No = col_double(),
  sample = col_character(),
  group = col_character(),
  time = col_character(),
  type = col_character(),
  seq = col_character(),
  rep = col_double()
)
bamfiles <- def_H3K27ac_bam$file #bamfiles <- def_bam$peakcall_bam


fragment_counts <- getCounts(def_H3K27ac_bam$file, TSSPM10kb_H3p3clus3_GR, 
                              paired =  FALSE,  # ChILはペアではない。
                              by_rg = FALSE, 
                              colData = DataFrame(Cell_Type = def_H3K27ac_bam$group,sample_name = def_H3K27ac_bam$sample))
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_UI_DoxMinus_H3K27ac_Rep01.bam
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_UI_DoxMinus_H3K27ac_Rep02.bam
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_UI_DoxPlus_H3K27ac_Rep01.bam
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_UI_DoxPlus_H3K27ac_Rep02.bam
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep01.bam
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep02.bam
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_0h_DoxPlus_H3K27ac_Rep01.bam
Reading in file: /home/guestA/n70275a/kTanaka/0110NOVAseq/mapped/20200501_3T3_EGFP18_0h_DoxPlus_H3K27ac_Rep02.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_24h_DoxMinus_H3K27ac_Rep01_runMerged.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_24h_DoxMinus_H3K27ac_Rep02_runMerged.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_24h_DoxPlus_H3K27ac_Rep01_runMerged.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_24h_DoxPlus_H3K27ac_Rep02_runMerged.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep01_runMerged.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep02_runMerged.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep01_runMerged.bam
Reading in file: /home/guestA/n70275a/kTanaka/0111NOVAseq/mapped/3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep02_runMerged.bam
length(fragment_counts)
[1] 55
print("---- fragment_counts ----")
[1] "---- fragment_counts ----"
slot(fragment_counts, "rowRanges") #fragment_counts @rowRanges
GRanges object with 55 ranges and 7 metadata columns:
       seqnames              ranges strand |           ens_gene       score       TSS    ext_gene        biotype H3p3cluster
          <Rle>           <IRanges>  <Rle> |        <character> <character> <integer> <character>    <character>   <integer>
   [1]     chr1   51279126-51299126      + | ENSMUSG00000045954           .  51289126      Cavin2 protein_coding           3
   [2]     chr1   75350329-75370329      + | ENSMUSG00000026208           .  75360329         Des protein_coding           3
   [3]     chr1 134279989-134299989      + | ENSMUSG00000026459           . 134289989        Myog protein_coding           3
   [4]     chr1 134322928-134342928      - | ENSMUSG00000026458           . 134332928      Ppfia4 protein_coding           3
   [5]     chr1 135365237-135385237      - | ENSMUSG00000041889           . 135375237      Shisa4 protein_coding           3
   ...      ...                 ...    ... .                ...         ...       ...         ...            ...         ...
  [51]    chr19     6986117-7006117      - | ENSMUSG00000037349           .   6996117      Nudt22 protein_coding           3
  [52]    chr19   34245590-34265590      - | ENSMUSG00000035783           .  34255590       Acta2 protein_coding           3
  [53]    chr19   40503779-40523779      - | ENSMUSG00000025006           .  40513779      Sorbs1 protein_coding           3
  [54]    chr19   42026000-42046000      + | ENSMUSG00000025172           .  42036000      Ankrd2 protein_coding           3
  [55]     chrX 167199315-167219315      - | ENSMUSG00000049775           . 167209315      Tmsb4x protein_coding           3
       BRBDEGcluster
            <factor>
   [1]             3
   [2]             3
   [3]             3
   [4]             3
   [5]             3
   ...           ...
  [51]             3
  [52]             3
  [53]             3
  [54]             3
  [55]             3
  -------
  seqinfo: 18 sequences from an unspecified genome; no seqlengths
slot(fragment_counts, "colData")
DataFrame with 16 rows and 3 columns
                                                               Cell_Type            sample_name     depth
                                                             <character>            <character> <numeric>
20200501_3T3_EGFP18_UI_DoxMinus_H3K27ac_Rep01.bam    H3K27ac_UI_DoxMinus  H3K27ac_UI_DoxMinus_1   2655505
20200501_3T3_EGFP18_UI_DoxMinus_H3K27ac_Rep02.bam    H3K27ac_UI_DoxMinus  H3K27ac_UI_DoxMinus_2   3467576
20200501_3T3_EGFP18_UI_DoxPlus_H3K27ac_Rep01.bam      H3K27ac_UI_DoxPlus   H3K27ac_UI_DoxPlus_1   3198781
20200501_3T3_EGFP18_UI_DoxPlus_H3K27ac_Rep02.bam      H3K27ac_UI_DoxPlus   H3K27ac_UI_DoxPlus_2   3038383
20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep01.bam    H3K27ac_0h_DoxMinus  H3K27ac_0h_DoxMinus_1   1959727
...                                                                  ...                    ...       ...
3T3_EGFP18_24h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_24h_DoxPlus  H3K27ac_24h_DoxPlus_2   1527310
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep01_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_1   1101851
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep02_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_2   1054200
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep01_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_1   1241266
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_2    889154
slot(fragment_counts, "NAMES")
NULL
slot(fragment_counts, "metadata")
list()
slot(fragment_counts, "elementMetadata")
DataFrame with 55 rows and 0 columns
slot(fragment_counts, "assays")
An object of class "SimpleAssays"
Slot "data":
List of length 1
names(1): counts
print("--------- save ----------------")
[1] "--------- save ----------------"
#-- save fragment count ----#
#--------#
type_depth <- slot(fragment_counts, "colData")  %>% as.data.frame() # 範囲
fffile <- sub(".csv","_typedepth.csv",peakfile)
print(fffile)
[1] "./Motif/TSSPM10kb_H3p3clus3_typedepth.csv"
type_depth %>% readr::write_csv(fffile)
#--------#
f_c_range <- fragment_counts @rowRanges  %>% as.data.frame() # 範囲
fc_range <- f_c_range %>% mutate(seqnames1=seqnames,start1=start,end1=end) %>% unite(sten,c(start1,end1),sep="-") %>% unite(range,c(seqnames1,sten),sep=":")

f_c_count <- fragment_counts @assays @data$counts %>% as.matrix() %>% as.data.frame()  # カウント
#---#
f_c_range_count <- cbind(fc_range, f_c_count)
nrow(f_c_range_count)
[1] 55
fffile <- sub(".csv","_fragcounts.csv",peakfile)
print(fffile)
[1] "./Motif/TSSPM10kb_H3p3clus3_fragcounts.csv"
f_c_range_count %>% readr::write_csv(fffile)
#---------------------------#

register(SerialParam())
fragment_counts_bias <- addGCBias(fragment_counts, genome = BSgenome.Mmusculus.UCSC.mm10) #ここでこけないように、Chrは確定されているものに設定。

#+++++++++++++++++++++++++++++++++++++++++++++++#
length(fragment_counts_bias)
[1] 55
print("---- fragment_counts_bias ----")
[1] "---- fragment_counts_bias ----"
print("== rowRanges ==")
[1] "== rowRanges =="
slot(fragment_counts_bias, "rowRanges")
GRanges object with 55 ranges and 8 metadata columns:
       seqnames              ranges strand |           ens_gene       score       TSS    ext_gene        biotype H3p3cluster
          <Rle>           <IRanges>  <Rle> |        <character> <character> <integer> <character>    <character>   <integer>
   [1]     chr1   51279126-51299126      + | ENSMUSG00000045954           .  51289126      Cavin2 protein_coding           3
   [2]     chr1   75350329-75370329      + | ENSMUSG00000026208           .  75360329         Des protein_coding           3
   [3]     chr1 134279989-134299989      + | ENSMUSG00000026459           . 134289989        Myog protein_coding           3
   [4]     chr1 134322928-134342928      - | ENSMUSG00000026458           . 134332928      Ppfia4 protein_coding           3
   [5]     chr1 135365237-135385237      - | ENSMUSG00000041889           . 135375237      Shisa4 protein_coding           3
   ...      ...                 ...    ... .                ...         ...       ...         ...            ...         ...
  [51]    chr19     6986117-7006117      - | ENSMUSG00000037349           .   6996117      Nudt22 protein_coding           3
  [52]    chr19   34245590-34265590      - | ENSMUSG00000035783           .  34255590       Acta2 protein_coding           3
  [53]    chr19   40503779-40523779      - | ENSMUSG00000025006           .  40513779      Sorbs1 protein_coding           3
  [54]    chr19   42026000-42046000      + | ENSMUSG00000025172           .  42036000      Ankrd2 protein_coding           3
  [55]     chrX 167199315-167219315      - | ENSMUSG00000049775           . 167209315      Tmsb4x protein_coding           3
       BRBDEGcluster      bias
            <factor> <numeric>
   [1]             3  0.418129
   [2]             3  0.492075
   [3]             3  0.498425
   [4]             3  0.521024
   [5]             3  0.501925
   ...           ...       ...
  [51]             3  0.535723
  [52]             3  0.421279
  [53]             3  0.459677
  [54]             3  0.495675
  [55]             3  0.429779
  -------
  seqinfo: 18 sequences from an unspecified genome; no seqlengths
print("== colData ==")
[1] "== colData =="
slot(fragment_counts_bias, "colData")
DataFrame with 16 rows and 3 columns
                                                               Cell_Type            sample_name     depth
                                                             <character>            <character> <numeric>
20200501_3T3_EGFP18_UI_DoxMinus_H3K27ac_Rep01.bam    H3K27ac_UI_DoxMinus  H3K27ac_UI_DoxMinus_1   2655505
20200501_3T3_EGFP18_UI_DoxMinus_H3K27ac_Rep02.bam    H3K27ac_UI_DoxMinus  H3K27ac_UI_DoxMinus_2   3467576
20200501_3T3_EGFP18_UI_DoxPlus_H3K27ac_Rep01.bam      H3K27ac_UI_DoxPlus   H3K27ac_UI_DoxPlus_1   3198781
20200501_3T3_EGFP18_UI_DoxPlus_H3K27ac_Rep02.bam      H3K27ac_UI_DoxPlus   H3K27ac_UI_DoxPlus_2   3038383
20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep01.bam    H3K27ac_0h_DoxMinus  H3K27ac_0h_DoxMinus_1   1959727
...                                                                  ...                    ...       ...
3T3_EGFP18_24h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_24h_DoxPlus  H3K27ac_24h_DoxPlus_2   1527310
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep01_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_1   1101851
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep02_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_2   1054200
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep01_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_1   1241266
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_2    889154
print("== NAMES ==")
[1] "== NAMES =="
slot(fragment_counts_bias, "NAMES")
NULL
print("== metadata ==")
[1] "== metadata =="
slot(fragment_counts_bias, "metadata")
list()
print("== elementMetadata ==")
[1] "== elementMetadata =="
slot(fragment_counts_bias, "elementMetadata")
DataFrame with 55 rows and 0 columns
print("== assays ==")
[1] "== assays =="
slot(fragment_counts_bias, "assays")
An object of class "SimpleAssays"
Slot "data":
List of length 1
names(1): counts
print("--------- save ----------------")
[1] "--------- save ----------------"
#-- save fragment count bias----#
f_c_range_bias <- fragment_counts_bias @rowRanges  %>% as.data.frame() # 範囲
fc_range_bias <- f_c_range_bias %>% mutate(seqnames1=seqnames,start1=start,end1=end) %>% unite(sten,c(start1,end1),sep="-") %>% unite(range,c(seqnames1,sten),sep=":")

f_c_count_bias <- fragment_counts_bias @assays @data$counts %>% as.matrix() %>% as.data.frame()  # カウント
#---#
f_c_range_count_bias <- cbind(fc_range_bias, f_c_count_bias)
nrow(f_c_range_count_bias)
[1] 55
fffile <- sub(".csv","_fragcounts_bias.csv",peakfile)
print(fffile)
[1] "./Motif/TSSPM10kb_H3p3clus3_fragcounts_bias.csv"
f_c_range_count_bias %>% readr::write_csv(fffile)
#---------------------------#
#counts_filtered <- filterSamples(fragment_counts_bias, min_depth = 1500, min_in_peaks = 0.15, shiny = FALSE)
counts_filtered_pre <- filterSamples(fragment_counts_bias, shiny = FALSE)
min_in_peaks set to 0.002
min_depth set to 161032.75
#++++++++++++++++++++++++++++++++++++++++++++++#
# If unspecified, min_in_peaks and min_depth cutoffs will be estimated based on data. min_in_peaks is set to 0.5 times the median proportion of fragments in peaks. min_depth is set to the maximum of 500 or 10 median library size.
#
# min_in_peaks: minimum fraction of samples within peaks
# min_depth:    minimum library size
# shiny:    make shiny gadget?
# ix_return:    return indices of sample to keep instead of subsetted counts object
#++++++++++++++++++++++++++++++++++++++++++++++#

length(counts_filtered_pre)
[1] 55
print("---- counts_filtered (pre) ----")
[1] "---- counts_filtered (pre) ----"
print("== rowRanges ==")
[1] "== rowRanges =="
slot(counts_filtered_pre, "rowRanges")
GRanges object with 55 ranges and 8 metadata columns:
       seqnames              ranges strand |           ens_gene       score       TSS    ext_gene        biotype H3p3cluster
          <Rle>           <IRanges>  <Rle> |        <character> <character> <integer> <character>    <character>   <integer>
   [1]     chr1   51279126-51299126      + | ENSMUSG00000045954           .  51289126      Cavin2 protein_coding           3
   [2]     chr1   75350329-75370329      + | ENSMUSG00000026208           .  75360329         Des protein_coding           3
   [3]     chr1 134279989-134299989      + | ENSMUSG00000026459           . 134289989        Myog protein_coding           3
   [4]     chr1 134322928-134342928      - | ENSMUSG00000026458           . 134332928      Ppfia4 protein_coding           3
   [5]     chr1 135365237-135385237      - | ENSMUSG00000041889           . 135375237      Shisa4 protein_coding           3
   ...      ...                 ...    ... .                ...         ...       ...         ...            ...         ...
  [51]    chr19     6986117-7006117      - | ENSMUSG00000037349           .   6996117      Nudt22 protein_coding           3
  [52]    chr19   34245590-34265590      - | ENSMUSG00000035783           .  34255590       Acta2 protein_coding           3
  [53]    chr19   40503779-40523779      - | ENSMUSG00000025006           .  40513779      Sorbs1 protein_coding           3
  [54]    chr19   42026000-42046000      + | ENSMUSG00000025172           .  42036000      Ankrd2 protein_coding           3
  [55]     chrX 167199315-167219315      - | ENSMUSG00000049775           . 167209315      Tmsb4x protein_coding           3
       BRBDEGcluster      bias
            <factor> <numeric>
   [1]             3  0.418129
   [2]             3  0.492075
   [3]             3  0.498425
   [4]             3  0.521024
   [5]             3  0.501925
   ...           ...       ...
  [51]             3  0.535723
  [52]             3  0.421279
  [53]             3  0.459677
  [54]             3  0.495675
  [55]             3  0.429779
  -------
  seqinfo: 18 sequences from an unspecified genome; no seqlengths
print("== colData ==")
[1] "== colData =="
slot(counts_filtered_pre, "colData")
DataFrame with 12 rows and 3 columns
                                                               Cell_Type            sample_name     depth
                                                             <character>            <character> <numeric>
20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep01.bam    H3K27ac_0h_DoxMinus  H3K27ac_0h_DoxMinus_1   1959727
20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep02.bam    H3K27ac_0h_DoxMinus  H3K27ac_0h_DoxMinus_2   1693345
20200501_3T3_EGFP18_0h_DoxPlus_H3K27ac_Rep01.bam      H3K27ac_0h_DoxPlus   H3K27ac_0h_DoxPlus_1   3424694
20200501_3T3_EGFP18_0h_DoxPlus_H3K27ac_Rep02.bam      H3K27ac_0h_DoxPlus   H3K27ac_0h_DoxPlus_2   2490017
3T3_EGFP18_24h_DoxMinus_H3K27ac_Rep01_runMerged.bam H3K27ac_24h_DoxMinus H3K27ac_24h_DoxMinus_1   1030885
...                                                                  ...                    ...       ...
3T3_EGFP18_24h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_24h_DoxPlus  H3K27ac_24h_DoxPlus_2   1527310
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep01_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_1   1101851
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep02_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_2   1054200
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep01_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_1   1241266
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_2    889154
print("== NAMES ==")
[1] "== NAMES =="
slot(counts_filtered_pre, "NAMES")
NULL
print("== metadata ==")
[1] "== metadata =="
slot(counts_filtered_pre, "metadata")
list()
print("== elementMetadata ==")
[1] "== elementMetadata =="
slot(counts_filtered_pre, "elementMetadata")
DataFrame with 55 rows and 0 columns
print("== assays ==")
[1] "== assays =="
slot(counts_filtered_pre, "assays")
An object of class "SimpleAssays"
Slot "data":
List of length 1
names(1): counts
print("-------------------------")
[1] "-------------------------"
counts_filtered <- filterPeaks(counts_filtered_pre,non_overlapping=TRUE)

#++++++++++++++++++++++++++++++++++++++++++++++#
# if non_overlapping is set to true, when peaks overlap the overlapping peak with lower counts is removed
#
# min_fragments_per_peak:   minimum number of fragmints in peaks across all samples
# non_overlapping:  reduce peak set to non-overlapping peaks, see details
# ix_return:    return indices of peaks to keep instead of subsetted counts object
#++++++++++++++++++++++++++++++++++++++++++++++#

length(counts_filtered)
[1] 55
print("---- counts_filtered ----")
[1] "---- counts_filtered ----"
slot(counts_filtered, "rowRanges")
GRanges object with 55 ranges and 8 metadata columns:
       seqnames              ranges strand |           ens_gene       score       TSS    ext_gene        biotype H3p3cluster
          <Rle>           <IRanges>  <Rle> |        <character> <character> <integer> <character>    <character>   <integer>
   [1]     chr1   51279126-51299126      + | ENSMUSG00000045954           .  51289126      Cavin2 protein_coding           3
   [2]     chr1   75350329-75370329      + | ENSMUSG00000026208           .  75360329         Des protein_coding           3
   [3]     chr1 134279989-134299989      + | ENSMUSG00000026459           . 134289989        Myog protein_coding           3
   [4]     chr1 134322928-134342928      - | ENSMUSG00000026458           . 134332928      Ppfia4 protein_coding           3
   [5]     chr1 135365237-135385237      - | ENSMUSG00000041889           . 135375237      Shisa4 protein_coding           3
   ...      ...                 ...    ... .                ...         ...       ...         ...            ...         ...
  [51]    chr19     6986117-7006117      - | ENSMUSG00000037349           .   6996117      Nudt22 protein_coding           3
  [52]    chr19   34245590-34265590      - | ENSMUSG00000035783           .  34255590       Acta2 protein_coding           3
  [53]    chr19   40503779-40523779      - | ENSMUSG00000025006           .  40513779      Sorbs1 protein_coding           3
  [54]    chr19   42026000-42046000      + | ENSMUSG00000025172           .  42036000      Ankrd2 protein_coding           3
  [55]     chrX 167199315-167219315      - | ENSMUSG00000049775           . 167209315      Tmsb4x protein_coding           3
       BRBDEGcluster      bias
            <factor> <numeric>
   [1]             3  0.418129
   [2]             3  0.492075
   [3]             3  0.498425
   [4]             3  0.521024
   [5]             3  0.501925
   ...           ...       ...
  [51]             3  0.535723
  [52]             3  0.421279
  [53]             3  0.459677
  [54]             3  0.495675
  [55]             3  0.429779
  -------
  seqinfo: 18 sequences from an unspecified genome; no seqlengths
slot(counts_filtered, "colData")
DataFrame with 12 rows and 3 columns
                                                               Cell_Type            sample_name     depth
                                                             <character>            <character> <numeric>
20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep01.bam    H3K27ac_0h_DoxMinus  H3K27ac_0h_DoxMinus_1   1959727
20200501_3T3_EGFP18_0h_DoxMinus_H3K27ac_Rep02.bam    H3K27ac_0h_DoxMinus  H3K27ac_0h_DoxMinus_2   1693345
20200501_3T3_EGFP18_0h_DoxPlus_H3K27ac_Rep01.bam      H3K27ac_0h_DoxPlus   H3K27ac_0h_DoxPlus_1   3424694
20200501_3T3_EGFP18_0h_DoxPlus_H3K27ac_Rep02.bam      H3K27ac_0h_DoxPlus   H3K27ac_0h_DoxPlus_2   2490017
3T3_EGFP18_24h_DoxMinus_H3K27ac_Rep01_runMerged.bam H3K27ac_24h_DoxMinus H3K27ac_24h_DoxMinus_1   1030885
...                                                                  ...                    ...       ...
3T3_EGFP18_24h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_24h_DoxPlus  H3K27ac_24h_DoxPlus_2   1527310
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep01_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_1   1101851
3T3_EGFP18_48h_DoxMinus_H3K27ac_Rep02_runMerged.bam H3K27ac_48h_DoxMinus H3K27ac_48h_DoxMinus_2   1054200
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep01_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_1   1241266
3T3_EGFP18_48h_DoxPlus_H3K27ac_Rep02_runMerged.bam   H3K27ac_48h_DoxPlus  H3K27ac_48h_DoxPlus_2    889154
slot(counts_filtered, "NAMES")
NULL
slot(counts_filtered, "metadata")
list()
slot(counts_filtered, "elementMetadata")
DataFrame with 55 rows and 0 columns
slot(counts_filtered, "assays")
An object of class "SimpleAssays"
Slot "data":
List of length 1
names(1): counts
print("-------------------------")
[1] "-------------------------"
#-- save counts_filtered ----#
f_c_range_countsfil <- counts_filtered @rowRanges  %>% as.data.frame() # 範囲
fc_range_countsfil <- f_c_range_countsfil %>% mutate(seqnames1=seqnames,start1=start,end1=end) %>% unite(sten,c(start1,end1),sep="-") %>% unite(range,c(seqnames1,sten),sep=":")

f_c_count_countsfil <- counts_filtered @assays @data$counts %>% as.matrix() %>% as.data.frame()  # カウント
#---#
f_c_range_count_countsfil <- cbind(fc_range_countsfil, f_c_count_countsfil)
nrow(f_c_range_count_countsfil)
[1] 55
fffile <- sub(".csv","_countsfilter.csv",peakfile)
print(fffile)
[1] "./Motif/TSSPM10kb_H3p3clus3_countsfilter.csv"
f_c_range_count_countsfil %>% readr::write_csv(fffile)
#---------------------------#

Raw deviations for background peaks & Bias corrected deviations and Z-scores


length(counts_filtered)
[1] 55
motifs <- chromVAR::getJasparMotifs(species = "Mus musculus", collection = "CORE") #OK
motif_ix <- matchMotifs(motifs, counts_filtered, genome = BSgenome.Mmusculus.UCSC.mm10)
#motifMatches(motif_ix) # Extract matches matrix from SummarizedExperiment result
dev <- computeDeviations(object = counts_filtered, annotations = motif_ix)
 .doLoadActions(where, attach) でエラー: 
  error in load action .__A__.1 for package nabor: loadModule(module, NULL, env = where, loadNow = TRUE): Unable to load module "class_WKNNF":  サイズ 1040604.2 Gb のベクトルを割り当てることができません 

ChromVARで エラーのためここで終了(20200819)

differentialDev

(20200617追加) https://greenleaflab.github.io/chromVAR/reference/differentialDeviations.html

data(mini_dev, package = “chromVAR”) difdev <- differentialDeviations(mini_dev, “Cell_Type”) differentialDeviations(object, groups, alternative = c(“two.sided”, “less”,“greater”), parametric = TRUE)

difdev <- differentialDeviations(dev, "Cell_Type", alternative = c("two.sided"))
 is(object, "chromVARDeviations") でエラー: 
   オブジェクト 'dev' がありません 

%>% filter(!motif_name %in% c(“Myod1”,“Myog”,“Tcf12”,“Tcf21”,“Ascl2”)) %>% filter(!motif_name %in% c(“FOS::JUN”,“Nfe2l2”,“Bach1::Mafk”)) %>% filter(!motif_name %in% c(“RUNX1”,“Myb”)) %>% filter(!motif_name %in% c(“Bcl6”,“Klf12”,“Klf4”,“Klf1”,“Gata4”,“Gata1”,“Rfx1”,“Spz1”,“Myc”,“Atoh1”))

%>% filter(motif_name %in% c(“Myod1”,“Myog”,“Tcf12”,“Tcf21”,“Ascl2”)) %>% filter(motif_name %in% c(“FOS::JUN”,“Nfe2l2”,“Bach1::Mafk”)) %>% filter(motif_name %in% c(“RUNX1”,“Myb”)) %>% filter(motif_name %in% c(“Bcl6”,“Klf12”,“Klf4”,“Klf1”,“Gata4”,“Gata1”,“Rfx1”,“Spz1”,“Myc”,“Atoh1”))

#+++++++++++++++++++++++++++++++++++++++++++++++#

print("---- motif_ix ----------------")
[1] "---- motif_ix ----------------"
motif_id <- motif_ix @colData %>% as_tibble(rownames = "motif_ID") %>% dplyr::rename(motif_name=name) #rename modif 20200616

print("-- motifMatches(motif_ix) --")
[1] "-- motifMatches(motif_ix) --"
## motifMatches が . or | で 入っている
motifM_table <- motifMatches(motif_ix) %>% as.matrix()  %>% as.data.frame()  #motifM_table <- motifMatches(motif_ix) %>% as.matrix()  %>% as.data.frame() as_tibble()
#motifM_table %>% dplyr::select(1:3)
#colnames(motifM_table) #colnames(motifMatches(motif_ix))
ncol(motifM_table) #ncol(motifMatches(motif_ix))
[1] 128
motifM_table_range <- cbind(fc_range_countsfil, motifM_table)
ncol(motifM_table_range)
[1] 142
#motifM_table_range <- cbind(fc_range_bias %>% dplyr::select(range) ,motifM_table)

print("---- save motif ----")
[1] "---- save motif ----"
#-- save motif id ----#
fffile <- paste("./bed_allpeak/",sub(".bed","_maxs_allpeak_deg_500_motifID.csv",basename(peakfile)),sep="")
print(fffile)
[1] "./bed_allpeak/TSSPM10kb_H3p3clus3.csv"
motif_id %>% readr::write_csv(fffile)
 ファイル './bed_allpeak/TSSPM10kb_H3p3clus3.csv' を開くことができません: そのようなファイルやディレクトリはありません  open.connection(path, "wb") でエラー: 
   コネクションを開くことができません 
LS0tCnRpdGxlOiAiVFNTcG01a2JfXzNUM19FR0ZQMThfRG94XzIwMjAwODExX19tYWluSDNwM19DaElMMDExMDAxMTFfQVRBQzAwNDlfQlJCMDQzMkwyIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKYXV0aG9yOiAiS3V3YWthZG8iCmRhdGU6ICIyMDIwLzgvMTEiCi0tLQoKCjIwMjAuOC4xMSBCUkLjgpLlho3op6PmnpAobG9nMkZD44KS6KiI566X44GZ44KL44Gf44KBKeOAgeOBneOCjOOBq+WQiOOCj+OBm+OBpuWGjeino+aekAoKYGBge3Igc2V0dGluZ30KCnByaW50KFN5cy5EYXRlKCkpCnByaW50KHNlc3Npb25JbmZvKCksbG9jYWxlPUZBTFNFKQoKYGBgCgpgYGB7ciBzZXR1cCAwfQoje3Igc2V0dXAgMCwgaW5jbHVkZT1GQUxTRX0ga25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQoKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHB1cnJyKQpzb3VyY2UoIi9ob21lL2d1ZXN0QS9uNzAyNzViL3dvcmsvcnNjcmlwdHMvZ2VvbU5vcm0uUiIpCgojIyDjg6njg5njg6vjgYLjgooKZ2dwb2ludHMgPC0gZnVuY3Rpb24oeCwuLi4pIAogIGdncGxvdCh4LC4uLikgKyBnZW9tX3BvaW50KHN0cm9rZT0xKSArCiAgZ2dyZXBlbDo6Z2VvbV90ZXh0X3JlcGVsKHNpemU9NCkgKyB0aGVtZV9taW5pbWFsKCkgKyBteWNvbG9yCgptYXhjaHJvbSA8LSAxOSAjIDE5OiBtb3VzZSwgMjI6IGh1bWFuCgpteWNvbG9yIDwtIGdnc2NpOjpzY2FsZV9jb2xvcl9hYWFzKCkKCiMgUENBL1VNQVAKc2NhbGVyb3dzIDwtIFRSVUUgIyBnZW5lLXdpc2Ugc2NhbGluZyAocGF0dGVybiBpcyB0aGUgbWF0dGVyPykKbnRvcCA8LSA1MDAgIyBudW1iZXIgb2YgdG9wLW4gZ2VuZXMgd2l0aCBoaWdoIHZhcmlhbmNlCnNlZWQgPC0gMTIzICMgc2V0IGFub3RoZXIgbnVtYmVyIGlmIFVNQVAgbG9va3Mgbm90IGdvb2QKbl9uZWkgPC0gNiAgIyBudW1iZXIgb2YgbmVpZ2hib3JpbmcgZGF0YSBwb2ludHMgaW4gVU1BUCAj44GT44GT44KS44Gp44GG44GX44Gf44KJ44GE44GE77yfCgoKIy0tLS0tLS0tLS0tLS0tLS0jCgojY2x1c3Rlcl9udW0gPC0gNCAKCmZpbGVwYXRoX3N1bW1hcnkgPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9DaElMU2VxMi9Lb21hdHN1XzNUM19FR0ZQX0gzbW0xOF9Eb3hfY2hJbF8wMTExTk9WQXNlcS9UU1NfY291bnQvQ2hJTEFsbF9UU1NfcG01a2Jfd2l0aEFUQUMvQ2hJTDAxMTAwMTExX0FUQUMwMDQ5TDFfXzNUM19FR0ZQMThfRG94X19UU1NfcG01a2JfMjAyMDA2MjQuY291bnQudHh0IgoKIyBkZWZ0YWJsZSDkv67mraPniYgKZmlsZXBhdGhfZGVmIDwtICIvaG9tZS9ndWVzdEEvbzcwNTc4YS9ha3V3YWthZG8va3V3YWthZG8vQ2hJTFNlcTIvS29tYXRzdV8zVDNfRUdGUF9IM21tMThfRG94X2NoSWxfMDExMU5PVkFzZXEvVFNTX2NvdW50L0NoSUxBbGxfVFNTX3BtNWtiX3dpdGhBVEFDL2RlZnRhYmxlX211bHRpY292X0NoSUwwMTEwMDExMV8yMDIwMDUwMV8zVDNfRUdGUDE4X1VJX0RveE1pbnVzX0gzcDNLMjdhY0s0S21lMzI3bWUzX3dpdGhBVEFDLnR4dCIKCgoKIy0tLSDjgrXjg7Pjg5fjg6vjga7pgbjmip4gLS0tIwoKZm9sZGVyX25hbWUgPC0gIkNoSUwgSDMuMywgSDNLMjdhYywgSDNLNG1lMywgSDNLMjdtZTMsIEFUQUMiICMiQ2hJTF9IM0syN21lM19IM0syN21lMyIKI3JlbW92ZV9zYW1wbGU9YygiRG94bWludXNfVUlfQVRBQ180IiwiRG94cGx1c19VSV9BVEFDXzQiLCJEb3htaW51c19ENDhfQVRBQ18xIiwiRG94bWludXNfRDQ4X0FUQUNfNCIsIkRveHBsdXNfRDQ4X0FUQUNfNCIpICPjgZPjga7jgrXjg7Pjg5fjg6vjgpLliYrpmaQoMjAxOTA5MTcpIDxBVEFD44Gu5aC05ZCIPgoKI3VzZSA8LSBxdW8oIShzYW1wbGUgJWluJSByZW1vdmVfc2FtcGxlKSkgI+OBk+OBruOCteODs+ODl+ODq+OCkuWJiumZpCgyMDE5MDkxNykKCiMtLS0gbXVsdGlCYW1TdW1tYXJ5IOOBrueVpSAtLS0jCiMg44OH44O844K/5L+d5a2Y55So44GucGF0aAojY3N2ZmlsZXBhdGggPC0gYmFzZW5hbWUoZmlsZXBhdGhfc3VtbWFyeSkgJT4lIHN1YigiLmNvdW50LnR4dCIsICJfXyIsIC4pCmNzdmZpbGVwYXRoIDwtIGJhc2VuYW1lKGZpbGVwYXRoX3N1bW1hcnkpICU+JSBzdWIoIi5jb3VudC50eHQiLCAiIiwgLikgICU+JSBzdWIoIkNoSUwwMTEwMDExMV9BVEFDMDA0OUwxX18zVDNfRUdGUDE4X0RveF9fIiwgIiIsIC4pCnByaW50KGNzdmZpbGVwYXRoKQoKCmBgYAoKIyMjIGVuc2VtYmxl44Gu44OH44O844K/44Gu6Kqt44G/6L6844G/CgpgYGB7ciBiaW9tYXJ0fQpmaWxlcGF0aF9CUkJlbnNlbWJsZSA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9MYXN0X1JzZXJ2ZXJfMjAwODExL2Vuc2VtYmxlX2xpc3RfdXNlYXN0LmNzdiIgI0JSQuOBruaZguOBrmdlbmXlkI3jg6rjgrnjg4gKCmVuc2VtYmxlIDwtIHJlYWRyOjpyZWFkX2NzdihmaWxlcGF0aF9CUkJlbnNlbWJsZSkgJT4lIG11dGF0ZV9pZihpcy5kb3VibGUsIGFzLmludGVnZXIpCgphbm5vdGF0ZSA8LSBwYXJ0aWFsKHJpZ2h0X2pvaW4sZW5zZW1ibGUsYnk9ImVuc19nZW5lIikgIzJndW7jgafkvb/jgYYKCmBgYAoKCgotLS0tLS0tLQoKIyMjIFNlbGVjdCByZWdpb25zCgoKVUNTQ+OBruW9ouW8j+OBruWgtOWQiCAoMjAxOTEwMTYpCgojIyMjIHVuaXRlIHRhYmxlcwoKYGBge3Igc2V0dXAgbXVsY292IDF9CgojIDIwMjAwNjE3CgpkZWZfbGlzdCA8LSByZWFkcjo6cmVhZF90c3YoZmlsZXBhdGhfZGVmKSAlPiUgbXV0YXRlKHNlcT1mYWN0b3Ioc2VxLCBjKCJBVEFDIiwiSDNwMyIsICJIM0syN2FjIiwiSDNLNG1lMyIsIkgzSzI3bWUzIikpKSAgJT4lIAptdXRhdGUodGltZTEgPSB0aW1lLCByZXAxPXJlcCkgJT4lIHVuaXRlKHRpbWUxLHJlcDEsY29sPSJ0aW1lX3JlcGxpY2F0ZSIpICAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwgIjBoIiwiMjRoIiwiNDhoIikpKSAlPiUgbXV0YXRlKHR5cGU9ZmFjdG9yKHR5cGUsYygiRG94UGx1cyIsIkRveE1pbnVzIikpKSAlPiUgbXV0YXRlKHJlcD1mYWN0b3IocmVwLCBjKCIxIiwgIjIiLCAiMyIsICI0IikpKSU+JSBtdXRhdGUodGltZV9yZXBsaWNhdGU9ZmFjdG9yKHRpbWVfcmVwbGljYXRlLGMoIlVJXzEiLCAiVUlfMiIsICJVSV8zIiwgIlVJXzQiLCAiMGhfMSIsIjBoXzIiLCIyNGhfMSIsIjI0aF8yIiwiNDhoXzEiLCI0OGhfMiIsIjQ4aF8zIiwiNDhoXzQiKSkpCgojZGVmX2xpc3QgPC0gcmVhZHI6OnJlYWRfdHN2KGZpbGVwYXRoX2RlZikgJT4lIG11dGF0ZShzZXE9ZmFjdG9yKHNlcSwgYygiSDNwMyIsICJIM0syN2FjIiwiSDNLNG1lMyIsIkgzSzI3bWUzIikpKSAgJT4lIAojbXV0YXRlKHRpbWUxID0gdGltZSwgcmVwMT1yZXApICU+JSB1bml0ZSh0aW1lMSxyZXAxLGNvbD0idGltZV9yZXBsaWNhdGUiKSAgJT4lIG11dGF0ZSh0aW1lPWZhY3Rvcih0aW1lLCBjKCJVSSIsICIwaCIsIjI0aCIsIjQ4aCIpKSkgJT4lIG11dGF0ZSh0eXBlPWZhY3Rvcih0eXBlLGMoIkRveFBsdXMiLCJEb3hNaW51cyIpKSkgJT4lIG11dGF0ZShyZXA9ZmFjdG9yKHJlcCwgYygiMSIsICIyIikpKSU+JSBtdXRhdGUodGltZV9yZXBsaWNhdGU9ZmFjdG9yKHRpbWVfcmVwbGljYXRlLGMoIlVJXzEiLCAiVUlfMiIsICIwaF8xIiwiMGhfMiIsIjI0aF8xIiwiMjRoXzIiLCI0OGhfMSIsIjQ4aF8yIikpKQoKCiMgYWRkIDIwMjAwNjE3Cmdyb3VwcyA8LSBjKAogICJBVEFDX1VJX0RveE1pbnVzIiwiQVRBQ19VSV9Eb3hQbHVzIiwKICAiQVRBQ180OGhfRG94TWludXMiLCJBVEFDXzQ4aF9Eb3hQbHVzIiwKICAKICAiSDNwM19VSV9Eb3hNaW51cyIsIkgzcDNfVUlfRG94UGx1cyIsCiAgIkgzcDNfMGhfRG94TWludXMiLCJIM3AzXzBoX0RveFBsdXMiLAogICJIM3AzXzI0aF9Eb3hNaW51cyIsIkgzcDNfMjRoX0RveFBsdXMiLAogICJIM3AzXzQ4aF9Eb3hNaW51cyIsIkgzcDNfNDhoX0RveFBsdXMiLAogIAogICJIM0syN2FjX1VJX0RveE1pbnVzIiwiSDNLMjdhY19VSV9Eb3hQbHVzIiwKICAiSDNLMjdhY18waF9Eb3hNaW51cyIsIkgzSzI3YWNfMGhfRG94UGx1cyIsCiAgIkgzSzI3YWNfMjRoX0RveE1pbnVzIiwiSDNLMjdhY18yNGhfRG94UGx1cyIsCiAgIkgzSzI3YWNfNDhoX0RveE1pbnVzIiwiSDNLMjdhY180OGhfRG94UGx1cyIsCiAgCiAgIkgzSzRtZTNfVUlfRG94TWludXMiLCJIM0s0bWUzX1VJX0RveFBsdXMiLAogICJIM0s0bWUzXzBoX0RveE1pbnVzIiwiSDNLNG1lM18waF9Eb3hQbHVzIiwKICAiSDNLNG1lM18yNGhfRG94TWludXMiLCJIM0s0bWUzXzI0aF9Eb3hQbHVzIiwKICAiSDNLNG1lM180OGhfRG94TWludXMiLCJIM0s0bWUzXzQ4aF9Eb3hQbHVzIiwKICAKICAiSDNLMjdtZTNfVUlfRG94TWludXMiLCJIM0syN21lM19VSV9Eb3hQbHVzIiwKICAiSDNLMjdtZTNfMGhfRG94TWludXMiLCJIM0syN21lM18waF9Eb3hQbHVzIiwKICAiSDNLMjdtZTNfMjRoX0RveE1pbnVzIiwiSDNLMjdtZTNfMjRoX0RveFBsdXMiLAogICJIM0syN21lM180OGhfRG94TWludXMiLCJIM0syN21lM180OGhfRG94UGx1cyIpCgpncm91cF9IM3AzIDwtIGMoCiAgIkgzcDNfVUlfRG94TWludXMiLCJIM3AzX1VJX0RveFBsdXMiLAogICJIM3AzXzBoX0RveE1pbnVzIiwiSDNwM18waF9Eb3hQbHVzIiwKICAiSDNwM18yNGhfRG94TWludXMiLCJIM3AzXzI0aF9Eb3hQbHVzIiwKICAiSDNwM180OGhfRG94TWludXMiLCJIM3AzXzQ4aF9Eb3hQbHVzIikKCmdyb3VwX0FUQUMgPC0gYygKICAiQVRBQ19VSV9Eb3hNaW51cyIsIkFUQUNfVUlfRG94UGx1cyIsCiAgIkFUQUNfNDhoX0RveE1pbnVzIiwiQVRBQ180OGhfRG94UGx1cyIpCgoKc2FtcGxlcyA8LSBjKAogICJBVEFDX1VJX0RveE1pbnVzXzEiLCJBVEFDX1VJX0RveE1pbnVzXzIiLCJBVEFDX1VJX0RveE1pbnVzXzMiLCJBVEFDX1VJX0RveE1pbnVzXzQiLAogICJBVEFDX1VJX0RveFBsdXNfMSIsIkFUQUNfVUlfRG94UGx1c18yIiwiQVRBQ19VSV9Eb3hQbHVzXzMiLCJBVEFDX1VJX0RveFBsdXNfNCIsCiAgIkFUQUNfNDhoX0RveE1pbnVzXzEiLCJBVEFDXzQ4aF9Eb3hNaW51c18yIiwiQVRBQ180OGhfRG94TWludXNfMyIsIkFUQUNfNDhoX0RveE1pbnVzXzQiLAogICJBVEFDXzQ4aF9Eb3hQbHVzXzEiLCJBVEFDXzQ4aF9Eb3hQbHVzXzIiLCJBVEFDXzQ4aF9Eb3hQbHVzXzMiLCJBVEFDXzQ4aF9Eb3hQbHVzXzQiLAogIAogICJIM3AzX1VJX0RveE1pbnVzXzEiLCJIM3AzX1VJX0RveE1pbnVzXzIiLCJIM3AzX1VJX0RveFBsdXNfMSIsIkgzcDNfVUlfRG94UGx1c18yIiwKICAiSDNwM18waF9Eb3hNaW51c18xIiwiSDNwM18waF9Eb3hNaW51c18yIiwiSDNwM18waF9Eb3hQbHVzXzEiLCJIM3AzXzBoX0RveFBsdXNfMiIsCiAgIkgzcDNfMjRoX0RveE1pbnVzXzEiLCJIM3AzXzI0aF9Eb3hNaW51c18yIiwiSDNwM18yNGhfRG94UGx1c18xIiwiSDNwM18yNGhfRG94UGx1c18yIiwKICAiSDNwM180OGhfRG94TWludXNfMSIsIkgzcDNfNDhoX0RveE1pbnVzXzIiLCJIM3AzXzQ4aF9Eb3hQbHVzXzEiLCJIM3AzXzQ4aF9Eb3hQbHVzXzIiLAogIAogICJIM0syN2FjX1VJX0RveE1pbnVzXzEiLCJIM0syN2FjX1VJX0RveE1pbnVzXzIiLCJIM0syN2FjX1VJX0RveFBsdXNfMSIsIkgzSzI3YWNfVUlfRG94UGx1c18yIiwKICAiSDNLMjdhY18waF9Eb3hNaW51c18xIiwiSDNLMjdhY18waF9Eb3hNaW51c18yIiwiSDNLMjdhY18waF9Eb3hQbHVzXzEiLCJIM0syN2FjXzBoX0RveFBsdXNfMiIsCiAgIkgzSzI3YWNfMjRoX0RveE1pbnVzXzEiLCJIM0syN2FjXzI0aF9Eb3hNaW51c18yIiwiSDNLMjdhY18yNGhfRG94UGx1c18xIiwiSDNLMjdhY18yNGhfRG94UGx1c18yIiwKICAiSDNLMjdhY180OGhfRG94TWludXNfMSIsIkgzSzI3YWNfNDhoX0RveE1pbnVzXzIiLCJIM0syN2FjXzQ4aF9Eb3hQbHVzXzEiLCJIM0syN2FjXzQ4aF9Eb3hQbHVzXzIiLAogIAogICJIM0s0bWUzX1VJX0RveE1pbnVzXzEiLCJIM0s0bWUzX1VJX0RveE1pbnVzXzIiLCJIM0s0bWUzX1VJX0RveFBsdXNfMSIsIkgzSzRtZTNfVUlfRG94UGx1c18yIiwKICAiSDNLNG1lM18waF9Eb3hNaW51c18xIiwiSDNLNG1lM18waF9Eb3hNaW51c18yIiwiSDNLNG1lM18waF9Eb3hQbHVzXzEiLCJIM0s0bWUzXzBoX0RveFBsdXNfMiIsCiAgIkgzSzRtZTNfMjRoX0RveE1pbnVzXzEiLCJIM0s0bWUzXzI0aF9Eb3hNaW51c18yIiwiSDNLNG1lM18yNGhfRG94UGx1c18xIiwiSDNLNG1lM18yNGhfRG94UGx1c18yIiwKICAiSDNLNG1lM180OGhfRG94TWludXNfMSIsIkgzSzRtZTNfNDhoX0RveE1pbnVzXzIiLCJIM0s0bWUzXzQ4aF9Eb3hQbHVzXzEiLCJIM0s0bWUzXzQ4aF9Eb3hQbHVzXzIiLAogIAogICJIM0syN21lM19VSV9Eb3hNaW51c18xIiwiSDNLMjdtZTNfVUlfRG94TWludXNfMiIsIkgzSzI3bWUzX1VJX0RveFBsdXNfMSIsIkgzSzI3bWUzX1VJX0RveFBsdXNfMiIsCiAgIkgzSzI3bWUzXzBoX0RveE1pbnVzXzEiLCJIM0syN21lM18waF9Eb3hNaW51c18yIiwiSDNLMjdtZTNfMGhfRG94UGx1c18xIiwiSDNLMjdtZTNfMGhfRG94UGx1c18yIiwKICAiSDNLMjdtZTNfMjRoX0RveE1pbnVzXzEiLCJIM0syN21lM18yNGhfRG94TWludXNfMiIsIkgzSzI3bWUzXzI0aF9Eb3hQbHVzXzEiLCJIM0syN21lM18yNGhfRG94UGx1c18yIiwKICAiSDNLMjdtZTNfNDhoX0RveE1pbnVzXzEiLCJIM0syN21lM180OGhfRG94TWludXNfMiIsIkgzSzI3bWUzXzQ4aF9Eb3hQbHVzXzEiLCJIM0syN21lM180OGhfRG94UGx1c18yIikKCnNhbXBsZXNfQVRBQyA8LSBjKAogICJBVEFDX1VJX0RveE1pbnVzXzEiLCJBVEFDX1VJX0RveE1pbnVzXzIiLCJBVEFDX1VJX0RveE1pbnVzXzMiLCJBVEFDX1VJX0RveE1pbnVzXzQiLAogICJBVEFDX1VJX0RveFBsdXNfMSIsIkFUQUNfVUlfRG94UGx1c18yIiwiQVRBQ19VSV9Eb3hQbHVzXzMiLCJBVEFDX1VJX0RveFBsdXNfNCIsCiAgIkFUQUNfNDhoX0RveE1pbnVzXzEiLCJBVEFDXzQ4aF9Eb3hNaW51c18yIiwiQVRBQ180OGhfRG94TWludXNfMyIsIkFUQUNfNDhoX0RveE1pbnVzXzQiLAogICJBVEFDXzQ4aF9Eb3hQbHVzXzEiLCJBVEFDXzQ4aF9Eb3hQbHVzXzIiLCJBVEFDXzQ4aF9Eb3hQbHVzXzMiLCJBVEFDXzQ4aF9Eb3hQbHVzXzQiKQoKc2FtcGxlc19IM3AzIDwtIGMoCiAgIkgzcDNfVUlfRG94TWludXNfMSIsIkgzcDNfVUlfRG94TWludXNfMiIsIkgzcDNfVUlfRG94UGx1c18xIiwiSDNwM19VSV9Eb3hQbHVzXzIiLAogICJIM3AzXzBoX0RveE1pbnVzXzEiLCJIM3AzXzBoX0RveE1pbnVzXzIiLCJIM3AzXzBoX0RveFBsdXNfMSIsIkgzcDNfMGhfRG94UGx1c18yIiwKICAiSDNwM18yNGhfRG94TWludXNfMSIsIkgzcDNfMjRoX0RveE1pbnVzXzIiLCJIM3AzXzI0aF9Eb3hQbHVzXzEiLCJIM3AzXzI0aF9Eb3hQbHVzXzIiLAogICJIM3AzXzQ4aF9Eb3hNaW51c18xIiwiSDNwM180OGhfRG94TWludXNfMiIsIkgzcDNfNDhoX0RveFBsdXNfMSIsIkgzcDNfNDhoX0RveFBsdXNfMiIpCgpzYW1wbGVzX0gzSzI3YWMgPC0gYygKICAiSDNLMjdhY19VSV9Eb3hNaW51c18xIiwiSDNLMjdhY19VSV9Eb3hNaW51c18yIiwiSDNLMjdhY19VSV9Eb3hQbHVzXzEiLCJIM0syN2FjX1VJX0RveFBsdXNfMiIsCiAgIkgzSzI3YWNfMGhfRG94TWludXNfMSIsIkgzSzI3YWNfMGhfRG94TWludXNfMiIsIkgzSzI3YWNfMGhfRG94UGx1c18xIiwiSDNLMjdhY18waF9Eb3hQbHVzXzIiLAogICJIM0syN2FjXzI0aF9Eb3hNaW51c18xIiwiSDNLMjdhY18yNGhfRG94TWludXNfMiIsIkgzSzI3YWNfMjRoX0RveFBsdXNfMSIsIkgzSzI3YWNfMjRoX0RveFBsdXNfMiIsCiAgIkgzSzI3YWNfNDhoX0RveE1pbnVzXzEiLCJIM0syN2FjXzQ4aF9Eb3hNaW51c18yIiwiSDNLMjdhY180OGhfRG94UGx1c18xIiwiSDNLMjdhY180OGhfRG94UGx1c18yIikKCnNhbXBsZXNfSDNLNG1lMyA8LSBjKAogICJIM0s0bWUzX1VJX0RveE1pbnVzXzEiLCJIM0s0bWUzX1VJX0RveE1pbnVzXzIiLCJIM0s0bWUzX1VJX0RveFBsdXNfMSIsIkgzSzRtZTNfVUlfRG94UGx1c18yIiwKICAiSDNLNG1lM18waF9Eb3hNaW51c18xIiwiSDNLNG1lM18waF9Eb3hNaW51c18yIiwiSDNLNG1lM18waF9Eb3hQbHVzXzEiLCJIM0s0bWUzXzBoX0RveFBsdXNfMiIsCiAgIkgzSzRtZTNfMjRoX0RveE1pbnVzXzEiLCJIM0s0bWUzXzI0aF9Eb3hNaW51c18yIiwiSDNLNG1lM18yNGhfRG94UGx1c18xIiwiSDNLNG1lM18yNGhfRG94UGx1c18yIiwKICAiSDNLNG1lM180OGhfRG94TWludXNfMSIsIkgzSzRtZTNfNDhoX0RveE1pbnVzXzIiLCJIM0s0bWUzXzQ4aF9Eb3hQbHVzXzEiLCJIM0s0bWUzXzQ4aF9Eb3hQbHVzXzIiKQoKc2FtcGxlc19IM0syN21lMyA8LSBjKAogICJIM0syN21lM19VSV9Eb3hNaW51c18xIiwiSDNLMjdtZTNfVUlfRG94TWludXNfMiIsIkgzSzI3bWUzX1VJX0RveFBsdXNfMSIsIkgzSzI3bWUzX1VJX0RveFBsdXNfMiIsCiAgIkgzSzI3bWUzXzBoX0RveE1pbnVzXzEiLCJIM0syN21lM18waF9Eb3hNaW51c18yIiwiSDNLMjdtZTNfMGhfRG94UGx1c18xIiwiSDNLMjdtZTNfMGhfRG94UGx1c18yIiwKICAiSDNLMjdtZTNfMjRoX0RveE1pbnVzXzEiLCJIM0syN21lM18yNGhfRG94TWludXNfMiIsIkgzSzI3bWUzXzI0aF9Eb3hQbHVzXzEiLCJIM0syN21lM18yNGhfRG94UGx1c18yIiwKICAiSDNLMjdtZTNfNDhoX0RveE1pbnVzXzEiLCJIM0syN21lM180OGhfRG94TWludXNfMiIsIkgzSzI3bWUzXzQ4aF9Eb3hQbHVzXzEiLCJIM0syN21lM180OGhfRG94UGx1c18yIikKCgoKCgoKZl9zYW1wbGUgPC0gZnVuY3Rpb24oeCkgeCAlPiUgbXV0YXRlKHNhbXBsZT1mYWN0b3Ioc2FtcGxlLCBzYW1wbGVzKSkKZl9ncm91cCA8LSBmdW5jdGlvbih4KSB4ICU+JSBtdXRhdGUoZ3JvdXA9ZmFjdG9yKGdyb3VwLCBncm91cHMpKQoKIyBmaWx0ZXIoc2FtcGxlIT0iRG94bWludXNfRDQ4X0FUQUNfMSIpID0+IGZpbHRlcigoc2FtcGxlIT0iRG94bWludXNfRDQ4X0FUQUNfMSIpJihyZXAhPSJsb3Q0IikpICgyMDIwIDAxMTTkv67mraMpCgojZGVmX2xpc3QgPC0gZGVmX2xpc3QgJT4lIGZfc2FtcGxlICU+JSBmX2dyb3VwCgojIyMjCmRlZl9saXN0X3NlbGVjdCA8LSBkZWZfbGlzdApkZWZfbGlzdF9zZWxlY3RfMCA8LSBkZWZfbGlzdCAgJT4lIGRwbHlyOjpzZWxlY3QoLSJmaWxlIiwtIm11bHRpY292X05vIikgJT4lIGZpbHRlcihzZXE9PSJBVEFDIikKZGVmX2xpc3Rfc2VsZWN0XzEgPC0gZGVmX2xpc3QgICU+JSBkcGx5cjo6c2VsZWN0KC0iZmlsZSIsLSJtdWx0aWNvdl9ObyIpICU+JSBmaWx0ZXIoc2VxPT0iSDNwMyIpCmRlZl9saXN0X3NlbGVjdF8yIDwtIGRlZl9saXN0ICAlPiUgZHBseXI6OnNlbGVjdCgtImZpbGUiLC0ibXVsdGljb3ZfTm8iKSAlPiUgZmlsdGVyKHNlcT09IkgzSzI3YWMiKQpkZWZfbGlzdF9zZWxlY3RfMyA8LSBkZWZfbGlzdCAgJT4lIGRwbHlyOjpzZWxlY3QoLSJmaWxlIiwtIm11bHRpY292X05vIikgJT4lIGZpbHRlcihzZXE9PSJIM0s0bWUzIikKZGVmX2xpc3Rfc2VsZWN0XzQgPC0gZGVmX2xpc3QgICU+JSBkcGx5cjo6c2VsZWN0KC0iZmlsZSIsLSJtdWx0aWNvdl9ObyIpICU+JSBmaWx0ZXIoc2VxPT0iSDNLMjdtZTMiKQoKI2RlZl9saXN0X3NlbGVjdCA8LSBkZWZfbGlzdCAlPiUgZmlsdGVyKCEhdXNlKSAj5L2/44KP44Gq44GE44K144Oz44OX44Or44KS5YmK6ZmkKDIwMTkwOTE3KQoKIyU+JSAKI211dGF0ZSh0aW1lMSA9IHRpbWUsIHJlcDE9cmVwKSAlPiUgdW5pdGUodGltZTEscmVwMSxjb2w9InRpbWVfcmVwbGljYXRlIikgJT4lICNtdXRhdGUodGltZV9yZXBsaWNhdGU9ZmFjdG9yKHRpbWVfcmVwbGljYXRlLGMoIlVJXzEiLCJVSV8yIiwiRDEiLCJENDhfbG90MiIpKSkKCiMgbmFycm93cGVhayDjga7loLTlkIggKOWei+OCkuaMh+WumikgMjAwNjEybW9kaWYgMjAwNjE1bW9kaWYKI25hcnJvd19jb2xuYW1lcyA8LSBjKCJjaHIiLCJzdGFydCIsImVuZCIsIm5hbWUiLCJzY29yZSIsInN0cmFuZCIsInNpbmduYWxWYWx1ZSIsInBWYWx1ZSIsInFWYWx1ZSIsInBlYWsiLCJjaHIwIiwic3RhcnQwIiwiZW5kMCIpCgptZXJnZV9jb2xuYW1lcyA8LSBjKCJjaHIiLCJUU1NzdGFydCIsIlRTU2VuZCIsImVuc19nZW5lIiwic2NvcmUiLCJzdHJhbmQiLCJUU1MiLCJTdGFydCIsIkVuZCIpCgptYXRvbWUwIDwtIHJlYWRyOjpyZWFkX3RzdihmaWxlcGF0aF9zdW1tYXJ5LCBjb2xfbmFtZXMgPSBjKG1lcmdlX2NvbG5hbWVzLCBkZWZfbGlzdCRzYW1wbGUpKSAgJT4lIG11dGF0ZV9pZihuYW1lcyguKSAlaW4lIGMoInN0YXJ0IiwiZW5kIiwiVFNTIiwiU3RhcnQiLCJFbmQiLGRlZl9saXN0JHNhbXBsZSksIGFzLmludGVnZXIpCgptYXRvbWUwICU+JSBkcGx5cjo6c2VsZWN0KCJjaHIiLCJUU1NzdGFydCIsIlRTU2VuZCIsImVuc19nZW5lIikgJT4lIHVuaXF1ZSgpICMgIyBBIHRpYmJsZTogMTA1LDE2NiB4IDQKCiNtYXRvbWUwICU+JSBncm91cF9ieShjaHIsZW5zX2dlbmUsc3RyYW5kLFN0YXJ0LEVuZCkgJT4lIHVuaXF1ZSgpICMgIyBBIHRpYmJsZTogMTA1LDE2NiB4IDQKCiNtYXRvbWUgPC0gbWF0b21lMCAlPiUgZ3JvdXBfYnkoY2hyLHN0YXJ0LGVuZCxOYW1lKSAlPiUgZHBseXI6OnRvcF9uKDEsIHNpbmduYWxWYWx1ZSkgICU+JSBkcGx5cjo6dG9wX24oMSwgcGVhaykgJT4lIGRwbHlyOjp1bmdyb3VwKCkKCiNtYXRvbWUgIDwtIG1hdG9tZTAgJT4lIGZpbHRlcl9hdChkZWZfbGlzdCRzYW1wbGUsYW55X3ZhcnMoLiA+IDApKQoKbWF0b21lMSA8LSBtYXRvbWUwICU+JSBnYXRoZXIoInNhbXBsZSIsICJjb3VudCIsIC0oImNociI6IkVuZCIpKSAlPiUgZmlsdGVyKHNhbXBsZSAlaW4lIGRlZl9saXN0X3NlbGVjdCRzYW1wbGUpICU+JSBsZWZ0X2pvaW4oZGVmX2xpc3Rfc2VsZWN0LCAuLGJ5ID0gInNhbXBsZSIpCgojICU+JSBkcGx5cjo6c2VsZWN0KC0ic2NvcmUiLC0ic3RyYW5kIiwtInNpbmduYWxWYWx1ZSIsLSJwVmFsdWUiLC0icVZhbHVlIiwtInBlYWsiKQoKIy0tLS0g56K66KqNIC0tLS0jCm1hdG9tZTAgJT4lIG5yb3coKQoKZmlsZW5hbWUgPC0gZ3N1YigiLnR4dCIsIl9fY291bnQuY3N2IixiYXNlbmFtZShmaWxlcGF0aF9zdW1tYXJ5KSkgICNnZW5l44Gr44Gk44GN6KSH5pWw6aCY5Z+fCm1hdG9tZTAgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmlsZW5hbWUpCnByaW50KGZpbGVuYW1lKQoKI2ZpbGVuYW1lIDwtIGdzdWIoIi50eHQiLCJfX3NlbGVjdF9uYW1lb25seS5jc3YiLGJhc2VuYW1lKGZpbGVwYXRoX2RlZikpCiNtYXRvbWUgJT4lIGRwbHlyOjpzZWxlY3QoImNociIsInN0YXJ0IiwiZW5kIiwibmFtZSIpICU+JSByZWFkcjo6d3JpdGVfY3N2KGZpbGVuYW1lKQojcHJpbnQoZmlsZW5hbWUpCgojbWF0b21lICU+JSBkcGx5cjo6c2VsZWN0KCJjaHIiLCJzdGFydCIsImVuZCIsIm5hbWUiLCJzY29yZSIsIk5hbWUiLCJzdHJhbmQiLCJzaW5nbmFsVmFsdWUiLCJwVmFsdWUiLCJxVmFsdWUiLCJwZWFrIiwiY2hyMCIsInN0YXJ0MCIsImVuZDAiKSAlPiUgcmVhZHI6OndyaXRlX2NzdihmaWxlbmFtZSkKI3ByaW50KGZpbGVuYW1lKQoKI21hdG9tZTAwIDwtIG1hdG9tZTAgJT4lIGdyb3VwX2J5KGNocixzdGFydCxlbmQsTmFtZSkgJT4lIHN1bW1hcmlzZShtYXhfc2NvcmU9bWF4KHNjb3JlKSwgcGFzdGUoTmFtZSwgY29sbGFwc2U9IiIpKSAjZHBseXI6OnRvcF9uKHNjb3JlLDEpCiAgCiNtYXRvbWUgPC0gbWF0b21lMCAlPiUgZmlsdGVyKG5hbWUgJWluJSBtYXRvbWUwMCRuYW1lKQoKI21hdG9tZSAlPiUgbXV0YXRlKG5hbWUxPW5hbWUpICU+JSBmaWx0ZXIoZ3JlcGwoIlthLXVdJCIsbmFtZSkpICU+JSBtdXRhdGUoTmFtZT1nc3ViKCJbYS11XSQiLCIiLG5hbWUpKQoKCiNtYXRfc2VsZWN0IDwtIG1hdG9tZSAlPiUgZHBseXI6OnNlbGVjdChjaHIsc3RhcnQsZW5kLG5hbWUsTmFtZSkgCiNhbm5vdGF0ZV9iZWQgPC0gcGFydGlhbChyaWdodF9qb2luLG1hdF9zZWxlY3QsYnk9ImVuc19nZW5lIikgIzJndW7jgafkvb/jgYYKCmBgYAoKCmBgYHtyIHNlbGVjdCBmaXJzdCBleG9uIFRTUyAyMDA3MDZ9CiNtYXRvbWUxX251bWJlciA8LSBtYXRvbWUxICU+JSBtdXRhdGUocG9zaXRpb24gPSByb3dfbnVtYmVyKCkpCiNtYXRvbWUxX3BsdXMgPC0gbWF0b21lMV9udW1iZXIgJT4lIGZpbHRlcihzdHJhbmQ9PSIrIikKI21hdG9tZTFfbWludXMgPC0gbWF0b21lMV9udW1iZXIgJT4lIGZpbHRlcihzdHJhbmQ9PSItIikKCm1hdG9tZTBfbnVtYmVyIDwtIG1hdG9tZTAgJT4lIG11dGF0ZShwb3NpdGlvbiA9IHJvd19udW1iZXIoKSkKbnJvdyhtYXRvbWUwX251bWJlcikKCm1hdG9tZTBfcGx1cyA8LSBtYXRvbWUwX251bWJlciAlPiUgZmlsdGVyKHN0cmFuZD09IisiKQptYXRvbWUwX21pbnVzIDwtIG1hdG9tZTBfbnVtYmVyICU+JSBmaWx0ZXIoc3RyYW5kPT0iLSIpCgptYXRvbWUwX3BsdXNfbyA8LSBtYXRvbWUwX3BsdXMgJT4lIGdyb3VwX2J5KGNocixlbnNfZ2VuZSkgJT4lIGRwbHlyOjp0b3BfbigtMSxUU1MpICPkvY4KbWF0b21lMF9taW51c19vIDwtIG1hdG9tZTBfbWludXMgJT4lIGdyb3VwX2J5KGNocixlbnNfZ2VuZSkgJT4lIGRwbHlyOjp0b3BfbigxLFRTUykgI+mrmAoKbWF0b21lMF9vIDwtIGRwbHlyOjpiaW5kX3Jvd3MobWF0b21lMF9wbHVzX28sIG1hdG9tZTBfbWludXNfbykgJT4lIGFycmFuZ2UocG9zaXRpb24pCm5yb3cobWF0b21lMF9vKQoKCgojIy0tLS0tIOeiuuiqjSAtLS0tLS0tLS0jIwpjb2xuYW1lcyhtYXRvbWUwX28pIApucm93KG1hdG9tZTBfbykKCmZpbGVuYW1lIDwtIGdzdWIoIi50eHQiLCJfX2NvdW50X2ZpcnN0VFNTLmNzdiIsYmFzZW5hbWUoZmlsZXBhdGhfc3VtbWFyeSkpICNnZW5l44Gr44Gk44GNMemgmOWfnwptYXRvbWUwX28gJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmlsZW5hbWUpCnByaW50KGZpbGVuYW1lKQoKIyMtLS0tLS0tLS0tLS0tLS0tLS0tLSMjCgojbWF0b21lMF9wbHVzICU+JSBmaWx0ZXIoZW5zX2dlbmUgPT0iRU5TTVVTRzAwMDAwMDAwMDM3IikgJT4lIGRwbHlyOjpzZWxlY3QoVFNTc3RhcnQscG9zaXRpb24pCiNtYXRvbWUwX3BsdXNfbyAlPiUgZmlsdGVyKGVuc19nZW5lID09IkVOU01VU0cwMDAwMDAwMDAzNyIpICU+JSBkcGx5cjo6c2VsZWN0KFRTU3N0YXJ0LHBvc2l0aW9uKQoKIyU+JSBncm91cF9ieShjaHIsVFNTc3RhcnQsVFNTZW5kLGVuc19nZW5lLHNjb3JlLHN0cmFuZCxUU1MsU3RhcnQsRW5kLHNlcSkgCgojbWF0b21lMV9udW1iZXIgJT4lIGZpbHRlcighKHN0cmFuZD09IisifHN0cmFuZD09Ii0iKSkKCmBgYAoKCgoKYGBge3Igc2VsZWN0IDIwMDcxNSBub3RNVH0KbWF0b21lMF9zIDwtIG1hdG9tZTBfbyAlPiUgIGRwbHlyOjpzZWxlY3QoY2hyLGVuc19nZW5lLFRTU3N0YXJ0LFRTU2VuZCxzY29yZSxzdHJhbmQsVFNTLFN0YXJ0LEVuZCxwb3NpdGlvbixhbGxfb2Yoc2FtcGxlcykpICU+JSBmaWx0ZXIoY2hyIT0iY2hyTSIpCm5yb3cobWF0b21lMF9zKQoKI21hdG9tZTBfcyA8LSBtYXRvbWUwX28gJT4lIGZpbHRlcihlbnNfZ2VuZSAlaW4lIEZDX3JhbmtfYWxsX0JSQmxpc3QkZW5zX2dlbmUpICU+JSBkcGx5cjo6c2VsZWN0KGNocixlbnNfZ2VuZSxUU1NzdGFydCxUU1NlbmQsc2NvcmUsc3RyYW5kLFRTUyxTdGFydCxFbmQscG9zaXRpb24sYWxsX29mKHNhbXBsZXMpKQpucm93KG1hdG9tZTBfcykKCiNtYXRvbWUwX3MxIDwtIG1hdG9tZTBfcyAlPiUgbGVmdF9qb2luKEZDX3JhbmtfYWxsX0JSQmxpc3QgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsbG9nMkZvbGRDaGFuZ2UsUmFuaykpCgptYXRvbWU1IDwtIG1hdG9tZTBfcyAlPiUgZHBseXI6OnNlbGVjdChjaHIsZW5zX2dlbmUscG9zaXRpb24sYWxsX29mKHNhbXBsZXMpKSAlPiUgdW5ncm91cCgpCgoKIyMtLS0tLSDnorroqo0gLS0tLS0tLS0tIyMKY29sbmFtZXMobWF0b21lMF9zKSAKbnJvdyhtYXRvbWUwX3MpCgpmaWxlbmFtZSA8LSBnc3ViKCIudHh0IiwiX19jb3VudF9maXJzdFRTU19zZWxlY3QuY3N2IixiYXNlbmFtZShmaWxlcGF0aF9zdW1tYXJ5KSkgICNnZW5l44Gr44Gk44GNMemgmOWfn+OAgeOBi+OBpEJSQuOBp25vcm1hbGl6ZWQgY291bnTjgYzjgYLjgovjgoLjga4gCm1hdG9tZTBfcyAlPiUgcmVhZHI6OndyaXRlX2NzdihmaWxlbmFtZSkKcHJpbnQoZmlsZW5hbWUpCgojIy0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKCmFubm90YXRlX1RTUyA8LSBwYXJ0aWFsKHJpZ2h0X2pvaW4sZHBseXI6OnNlbGVjdChtYXRvbWUwX3MsY2hyLGVuc19nZW5lLFRTU3N0YXJ0LFRTU2VuZCxzY29yZSxzdHJhbmQsVFNTLFN0YXJ0LEVuZCxwb3NpdGlvbiksYnk9ImVuc19nZW5lIikgIzJndW7jgafkvb/jgYYKYGBgCgoKIyMgbm9ybWFsaXplZCBjb3VudAoKc2VwYXJhdGUgbWF0cml4CgoKYGBge3Igc2V0dXAgbWF0cml4IERlc2VxMiBwYXJ0MSAyMDA3MDd9Cgpucm93KG1hdG9tZTUpCmNvbG5hbWVzKG1hdG9tZTUpCgpYIDwtIG1hdG9tZTUgJT4lIGRwbHlyOjpzZWxlY3QoYWxsX29mKHNhbXBsZXMpKSAlPiUgYXMubWF0cml4CnJvd25hbWVzKFgpIDwtIG1hdG9tZTUkZW5zX2dlbmUKCiMjIy0tLSBERVNlcTLjgavjgojjgopub3JtYWxpemVkIGNvdW50ICjlv4XopoHjgarjgrXjg7Pjg5fjg6vjga7jgb8pIC0tLSMjIwptb2RlbDwtIH5ncm91cApkZHNfQVRBQyA8LSBERVNlcTI6OkRFU2VxRGF0YVNldEZyb21NYXRyaXgoWFssZGVmX2xpc3Rfc2VsZWN0XzAkc2FtcGxlXSxkZWZfbGlzdF9zZWxlY3RfMCxtb2RlbCkgI0FUQUMKZGRzX0gzcDMgPC0gREVTZXEyOjpERVNlcURhdGFTZXRGcm9tTWF0cml4KFhbLGRlZl9saXN0X3NlbGVjdF8xJHNhbXBsZV0sZGVmX2xpc3Rfc2VsZWN0XzEsbW9kZWwpICNIM3AzCmRkc19IM0syN2FjIDwtIERFU2VxMjo6REVTZXFEYXRhU2V0RnJvbU1hdHJpeChYWyxkZWZfbGlzdF9zZWxlY3RfMiRzYW1wbGVdLGRlZl9saXN0X3NlbGVjdF8yLG1vZGVsKSAjSDNLMjdhYwpkZHNfSDNLNG1lMyA8LSBERVNlcTI6OkRFU2VxRGF0YVNldEZyb21NYXRyaXgoWFssZGVmX2xpc3Rfc2VsZWN0XzMkc2FtcGxlXSxkZWZfbGlzdF9zZWxlY3RfMyxtb2RlbCkgI0gzSzRtZTMKZGRzX0gzSzI3bWUzIDwtIERFU2VxMjo6REVTZXFEYXRhU2V0RnJvbU1hdHJpeChYWyxkZWZfbGlzdF9zZWxlY3RfNCRzYW1wbGVdLGRlZl9saXN0X3NlbGVjdF80LG1vZGVsKSAjSDNLMjdtZTMKCmBgYAoKIyMjIyBGaXQgbW9kZWwKCmBgYHtyIGRlc2VxMiAyZ3VufQojbW9kZWxfMmd1biA8LSB+Z3JvdXAKI2Rkc18yZ3VuIDwtIERFU2VxMjo6REVTZXFEYXRhU2V0RnJvbU1hdHJpeChYWyxkZWZfbGlzdF9zZWxlY3Qkc2FtcGxlXSxkZWZfbGlzdF9zZWxlY3QsbW9kZWxfMmd1bikKZGRzX0FUQUMgPC0gREVTZXEyOjpERVNlcShkZHNfQVRBQykKZGRzX0gzcDMgPC0gREVTZXEyOjpERVNlcShkZHNfSDNwMykKZGRzX0gzSzI3YWMgPC0gREVTZXEyOjpERVNlcShkZHNfSDNLMjdhYykKZGRzX0gzSzRtZTMgPC0gREVTZXEyOjpERVNlcShkZHNfSDNLNG1lMykKZGRzX0gzSzI3bWUzIDwtIERFU2VxMjo6REVTZXEoZGRzX0gzSzI3bWUzKQoKI2tlZXAgPC0gcm93U3Vtcyhjb3VudHMoZGRzKSkgPj0gMTAgI2xvdyBjb3VudOOBr+WJiuOCi+aWueazlQojZGRzIDwtIGRkc1trZWVwLF0gI2xvdyBjb3VudOOBr+WJiuOCi+aWueazlQoKYGBgCgoKIyMjIyBEaWFnbm9zdGljcyBwbG90CgpgYGB7ciBkaWFnbm9zdGljcyAyZ3VuLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NX0KREVTZXEyOjpzaXplRmFjdG9ycyhkZHNfQVRBQykgJT4lCiAge3RpYmJsZShzYW1wbGU9bmFtZXMoLiksc2l6ZUZhY3Rvcj0uKX0gJT4lCiAgZ2dwbG90KGFlcyhzYW1wbGUsc2l6ZUZhY3RvcikpICsgdGhlbWVfbWluaW1hbCgpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgY29vcmRfZmxpcCgpCkRFU2VxMjo6cGxvdERpc3BFc3RzKGRkc19BVEFDKQoKREVTZXEyOjpzaXplRmFjdG9ycyhkZHNfSDNwMykgJT4lCiAge3RpYmJsZShzYW1wbGU9bmFtZXMoLiksc2l6ZUZhY3Rvcj0uKX0gJT4lCiAgZ2dwbG90KGFlcyhzYW1wbGUsc2l6ZUZhY3RvcikpICsgdGhlbWVfbWluaW1hbCgpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgY29vcmRfZmxpcCgpCkRFU2VxMjo6cGxvdERpc3BFc3RzKGRkc19IM3AzKQoKREVTZXEyOjpzaXplRmFjdG9ycyhkZHNfSDNLMjdhYykgJT4lCiAge3RpYmJsZShzYW1wbGU9bmFtZXMoLiksc2l6ZUZhY3Rvcj0uKX0gJT4lCiAgZ2dwbG90KGFlcyhzYW1wbGUsc2l6ZUZhY3RvcikpICsgdGhlbWVfbWluaW1hbCgpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgY29vcmRfZmxpcCgpCkRFU2VxMjo6cGxvdERpc3BFc3RzKGRkc19IM0syN2FjKQoKREVTZXEyOjpzaXplRmFjdG9ycyhkZHNfSDNLNG1lMykgJT4lCiAge3RpYmJsZShzYW1wbGU9bmFtZXMoLiksc2l6ZUZhY3Rvcj0uKX0gJT4lCiAgZ2dwbG90KGFlcyhzYW1wbGUsc2l6ZUZhY3RvcikpICsgdGhlbWVfbWluaW1hbCgpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgY29vcmRfZmxpcCgpCkRFU2VxMjo6cGxvdERpc3BFc3RzKGRkc19IM0s0bWUzKQoKREVTZXEyOjpzaXplRmFjdG9ycyhkZHNfSDNLMjdtZTMpICU+JQogIHt0aWJibGUoc2FtcGxlPW5hbWVzKC4pLHNpemVGYWN0b3I9Lil9ICU+JQogIGdncGxvdChhZXMoc2FtcGxlLHNpemVGYWN0b3IpKSArIHRoZW1lX21pbmltYWwoKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIGNvb3JkX2ZsaXAoKQpERVNlcTI6OnBsb3REaXNwRXN0cyhkZHNfSDNLMjdtZTMpCmBgYAoKCm5vcm1hbGl6ZWQgY291bnQgbGlzdOOCkuabuOOBjeWHuuOBlwoKYGBge3Igc2V0dXAgbWF0cml4IERlc2VxMiBwYXJ0MiAyMDA3MDd9CgojIEFUQUMKZGRzX0FUQUMgPC0gREVTZXEyOjplc3RpbWF0ZVNpemVGYWN0b3JzKGRkc19BVEFDKQpub3JtX0FUQUMgPC0gREVTZXEyOjpjb3VudHMoZGRzX0FUQUMsbm9ybWFsaXplZD1UUlVFKSAjREVH44KS5Y+W44Gj44Gf5b6M44Gu44Kv44Op44K544K/44Oq44Oz44Kw44Gr5L2/44GG44CCCgpub3JtYWxpemVkY291bnRfQVRBQyA8LSBhcy5kYXRhLmZyYW1lKG5vcm1fQVRBQykgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJlbnNfZ2VuZSIpICU+JSBhc190aWJibGUgJT4lIGRwbHlyOjpzZWxlY3QoImVuc19nZW5lIiwgYWxsX29mKGRlZl9saXN0X3NlbGVjdF8wJHNhbXBsZSkpCmZpbGVuYW1lIDwtIHBhc3RlKGNzdmZpbGVwYXRoLCJfbm9ybWNvdW50X0FUQUMuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdihub3JtYWxpemVkY291bnRfQVRBQywgZmlsZW5hbWUpCm5yb3cobm9ybWFsaXplZGNvdW50X0FUQUMpCm5jb2wobm9ybWFsaXplZGNvdW50X0FUQUMpCgpub3JtX2dlbmVfQVRBQyA8LSBub3JtYWxpemVkY291bnRfQVRBQyAlPiUgaW5uZXJfam9pbihlbnNlbWJsZSkgJT4lIGRwbHlyOjpzZWxlY3QoImVuc19nZW5lIiwiZXh0X2dlbmUiLCAiYmlvdHlwZSIsImNociIsIGFsbF9vZihkZWZfbGlzdF9zZWxlY3RfMCRzYW1wbGUpKQpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX25vcm1jb3VudF9BVEFDX2dlbmVuYW1lLmNzdiIsc2VwPSJfIikKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3Yobm9ybV9nZW5lX0FUQUMsIGZpbGVuYW1lKQpucm93KG5vcm1fZ2VuZV9BVEFDKQpuY29sKG5vcm1fZ2VuZV9BVEFDKQoKCiMgSDNwMwpkZHNfSDNwMyA8LSBERVNlcTI6OmVzdGltYXRlU2l6ZUZhY3RvcnMoZGRzX0gzcDMpCm5vcm1fSDNwMyA8LSBERVNlcTI6OmNvdW50cyhkZHNfSDNwMyxub3JtYWxpemVkPVRSVUUpICNERUfjgpLlj5bjgaPjgZ/lvozjga7jgq/jg6njgrnjgr/jg6rjg7PjgrDjgavkvb/jgYbjgIIKCm5vcm1hbGl6ZWRjb3VudF9IM3AzIDwtIGFzLmRhdGEuZnJhbWUobm9ybV9IM3AzKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImVuc19nZW5lIikgJT4lIGFzX3RpYmJsZSAlPiUgZHBseXI6OnNlbGVjdCgiZW5zX2dlbmUiLCBhbGxfb2YoZGVmX2xpc3Rfc2VsZWN0XzEkc2FtcGxlKSkKZmlsZW5hbWUgPC0gcGFzdGUoY3N2ZmlsZXBhdGgsIl9ub3JtY291bnRfSDNwMy5jc3YiLHNlcD0iXyIpCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KG5vcm1hbGl6ZWRjb3VudF9IM3AzLCBmaWxlbmFtZSkKbnJvdyhub3JtYWxpemVkY291bnRfSDNwMykKbmNvbChub3JtYWxpemVkY291bnRfSDNwMykKCm5vcm1fZ2VuZV9IM3AzIDwtIG5vcm1hbGl6ZWRjb3VudF9IM3AzICU+JSBpbm5lcl9qb2luKGVuc2VtYmxlKSAlPiUgZHBseXI6OnNlbGVjdCgiZW5zX2dlbmUiLCJleHRfZ2VuZSIsICJiaW90eXBlIiwiY2hyIiwgYWxsX29mKGRlZl9saXN0X3NlbGVjdF8xJHNhbXBsZSkpCmZpbGVuYW1lIDwtIHBhc3RlKGNzdmZpbGVwYXRoLCJfbm9ybWNvdW50X0gzcDNfZ2VuZW5hbWUuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdihub3JtX2dlbmVfSDNwMywgZmlsZW5hbWUpCm5yb3cobm9ybV9nZW5lX0gzcDMpCm5jb2wobm9ybV9nZW5lX0gzcDMpCgoKIyBIM0syN2FjCmRkc19IM0syN2FjIDwtIERFU2VxMjo6ZXN0aW1hdGVTaXplRmFjdG9ycyhkZHNfSDNLMjdhYykKbm9ybV9IM0syN2FjIDwtIERFU2VxMjo6Y291bnRzKGRkc19IM0syN2FjLG5vcm1hbGl6ZWQ9VFJVRSkgI0RFR+OCkuWPluOBo+OBn+W+jOOBruOCr+ODqeOCueOCv+ODquODs+OCsOOBq+S9v+OBhuOAggoKbm9ybWFsaXplZGNvdW50X0gzSzI3YWMgPC0gYXMuZGF0YS5mcmFtZShub3JtX0gzSzI3YWMpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiZW5zX2dlbmUiKSAlPiUgYXNfdGliYmxlICU+JSBkcGx5cjo6c2VsZWN0KCJlbnNfZ2VuZSIsIGFsbF9vZihkZWZfbGlzdF9zZWxlY3RfMiRzYW1wbGUpKQpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX25vcm1jb3VudF9IM0syN2FjLmNzdiIsc2VwPSJfIikKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3Yobm9ybWFsaXplZGNvdW50X0gzSzI3YWMsIGZpbGVuYW1lKQpucm93KG5vcm1hbGl6ZWRjb3VudF9IM0syN2FjKQpuY29sKG5vcm1hbGl6ZWRjb3VudF9IM0syN2FjKQoKbm9ybV9nZW5lX0gzSzI3YWMgPC0gbm9ybWFsaXplZGNvdW50X0gzSzI3YWMgJT4lIGlubmVyX2pvaW4oZW5zZW1ibGUpICU+JSBkcGx5cjo6c2VsZWN0KCJlbnNfZ2VuZSIsImV4dF9nZW5lIiwgImJpb3R5cGUiLCJjaHIiLCBhbGxfb2YoZGVmX2xpc3Rfc2VsZWN0XzIkc2FtcGxlKSkKZmlsZW5hbWUgPC0gcGFzdGUoY3N2ZmlsZXBhdGgsIl9ub3JtY291bnRfSDNLMjdhY19nZW5lbmFtZS5jc3YiLHNlcD0iXyIpCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KG5vcm1fZ2VuZV9IM0syN2FjLCBmaWxlbmFtZSkKbnJvdyhub3JtX2dlbmVfSDNLMjdhYykKbmNvbChub3JtX2dlbmVfSDNLMjdhYykKCiMgSDNLNG1lMwpkZHNfSDNLNG1lMyA8LSBERVNlcTI6OmVzdGltYXRlU2l6ZUZhY3RvcnMoZGRzX0gzSzRtZTMpCm5vcm1fSDNLNG1lMyA8LSBERVNlcTI6OmNvdW50cyhkZHNfSDNLNG1lMyxub3JtYWxpemVkPVRSVUUpICNERUfjgpLlj5bjgaPjgZ/lvozjga7jgq/jg6njgrnjgr/jg6rjg7PjgrDjgavkvb/jgYbjgIIKCm5vcm1hbGl6ZWRjb3VudF9IM0s0bWUzIDwtIGFzLmRhdGEuZnJhbWUobm9ybV9IM0s0bWUzKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImVuc19nZW5lIikgJT4lIGFzX3RpYmJsZSAlPiUgZHBseXI6OnNlbGVjdCgiZW5zX2dlbmUiLCBhbGxfb2YoZGVmX2xpc3Rfc2VsZWN0XzMkc2FtcGxlKSkKZmlsZW5hbWUgPC0gcGFzdGUoY3N2ZmlsZXBhdGgsIl9ub3JtY291bnRfSDNLNG1lMy5jc3YiLHNlcD0iXyIpCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KG5vcm1hbGl6ZWRjb3VudF9IM0s0bWUzLCBmaWxlbmFtZSkKbnJvdyhub3JtYWxpemVkY291bnRfSDNLNG1lMykKbmNvbChub3JtYWxpemVkY291bnRfSDNLNG1lMykKCm5vcm1fZ2VuZV9IM0s0bWUzIDwtIG5vcm1hbGl6ZWRjb3VudF9IM0s0bWUzICU+JSBpbm5lcl9qb2luKGVuc2VtYmxlKSAlPiUgZHBseXI6OnNlbGVjdCgiZW5zX2dlbmUiLCJleHRfZ2VuZSIsICJiaW90eXBlIiwiY2hyIiwgYWxsX29mKGRlZl9saXN0X3NlbGVjdF8zJHNhbXBsZSkpCmZpbGVuYW1lIDwtIHBhc3RlKGNzdmZpbGVwYXRoLCJfbm9ybWNvdW50X0gzSzRtZTNfZ2VuZW5hbWUuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdihub3JtX2dlbmVfSDNLNG1lMywgZmlsZW5hbWUpCm5yb3cobm9ybV9nZW5lX0gzSzRtZTMpCm5jb2wobm9ybV9nZW5lX0gzSzRtZTMpCgojIEgzSzI3bWUzCmRkc19IM0syN21lMyA8LSBERVNlcTI6OmVzdGltYXRlU2l6ZUZhY3RvcnMoZGRzX0gzSzI3bWUzKQpub3JtX0gzSzI3bWUzIDwtIERFU2VxMjo6Y291bnRzKGRkc19IM0syN21lMyxub3JtYWxpemVkPVRSVUUpICNERUfjgpLlj5bjgaPjgZ/lvozjga7jgq/jg6njgrnjgr/jg6rjg7PjgrDjgavkvb/jgYbjgIIKCm5vcm1hbGl6ZWRjb3VudF9IM0syN21lMyA8LSBhcy5kYXRhLmZyYW1lKG5vcm1fSDNLMjdtZTMpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiZW5zX2dlbmUiKSAlPiUgYXNfdGliYmxlICU+JSBkcGx5cjo6c2VsZWN0KCJlbnNfZ2VuZSIsIGFsbF9vZihkZWZfbGlzdF9zZWxlY3RfNCRzYW1wbGUpKQpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX25vcm1jb3VudF9IM0syN21lMy5jc3YiLHNlcD0iXyIpCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KG5vcm1hbGl6ZWRjb3VudF9IM0syN21lMywgZmlsZW5hbWUpCm5yb3cobm9ybWFsaXplZGNvdW50X0gzSzI3bWUzKQpuY29sKG5vcm1hbGl6ZWRjb3VudF9IM0syN21lMykKCm5vcm1fZ2VuZV9IM0syN21lMyA8LSBub3JtYWxpemVkY291bnRfSDNLMjdtZTMgJT4lIGlubmVyX2pvaW4oZW5zZW1ibGUpICU+JSBkcGx5cjo6c2VsZWN0KCJlbnNfZ2VuZSIsImV4dF9nZW5lIiwgImJpb3R5cGUiLCJjaHIiLCBhbGxfb2YoZGVmX2xpc3Rfc2VsZWN0XzQkc2FtcGxlKSkKZmlsZW5hbWUgPC0gcGFzdGUoY3N2ZmlsZXBhdGgsIl9ub3JtY291bnRfSDNLMjdtZTNfZ2VuZW5hbWUuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdihub3JtX2dlbmVfSDNLMjdtZTMsIGZpbGVuYW1lKQpucm93KG5vcm1fZ2VuZV9IM0syN21lMykKbmNvbChub3JtX2dlbmVfSDNLMjdtZTMpCgoKIyBiaW5kIG5vcm0gY291bnQKbm9ybWFsaXplZGNvdW50IDwtIG5vcm1hbGl6ZWRjb3VudF9BVEFDICU+JSBpbm5lcl9qb2luKG5vcm1hbGl6ZWRjb3VudF9IM3AzKSAlPiUgaW5uZXJfam9pbihub3JtYWxpemVkY291bnRfSDNLMjdhYykgJT4lIGlubmVyX2pvaW4obm9ybWFsaXplZGNvdW50X0gzSzRtZTMpICU+JSBpbm5lcl9qb2luKG5vcm1hbGl6ZWRjb3VudF9IM0syN21lMykKbm9ybV9nZW5lIDwtIG5vcm1fZ2VuZV9BVEFDICU+JSBpbm5lcl9qb2luKG5vcm1fZ2VuZV9IM3AzKSAlPiUgaW5uZXJfam9pbihub3JtX2dlbmVfSDNLMjdhYykgJT4lIGlubmVyX2pvaW4obm9ybV9nZW5lX0gzSzRtZTMpICU+JSBpbm5lcl9qb2luKG5vcm1fZ2VuZV9IM0syN21lMykKCnByaW50KG5vcm1fZ2VuZSkKY29sbmFtZXMobm9ybV9nZW5lKQoKZmlsZW5hbWUgPC0gcGFzdGUoY3N2ZmlsZXBhdGgsIl9ub3JtY291bnQuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdihub3JtYWxpemVkY291bnQsIGZpbGVuYW1lKQoKZmlsZW5hbWUgPC0gcGFzdGUoY3N2ZmlsZXBhdGgsIl9ub3JtY291bnRfZ2VuZW5hbWUuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdihub3JtX2dlbmUsIGZpbGVuYW1lKQoKCmBgYAoKc2l6ZSBmYWN0b3JzIOOCkuabuOOBjeWHuuOBlwoKYGBge3Igc2V0dXAgbWF0cml4IERlc2VxMiBwYXJ0MyAyMDA3MDd9CgpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX3NpemVmYWN0b3JzX0FUQUMuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKYXMuZGF0YS5mcmFtZShERVNlcTI6OnNpemVGYWN0b3JzKGRkc19BVEFDKSkgICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigic2FtcGxlIikgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmlsZW5hbWUpCgpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX3NpemVmYWN0b3JzX0gzcDMuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKYXMuZGF0YS5mcmFtZShERVNlcTI6OnNpemVGYWN0b3JzKGRkc19IM3AzKSkgICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigic2FtcGxlIikgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmlsZW5hbWUpCgpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX3NpemVmYWN0b3JzX0gzSzI3YWMuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKYXMuZGF0YS5mcmFtZShERVNlcTI6OnNpemVGYWN0b3JzKGRkc19IM0syN2FjKSkgICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigic2FtcGxlIikgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmlsZW5hbWUpCgpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX3NpemVmYWN0b3JzX0gzSzRtZTMuY3N2IixzZXA9Il8iKQpwcmludChmaWxlbmFtZSkKYXMuZGF0YS5mcmFtZShERVNlcTI6OnNpemVGYWN0b3JzKGRkc19IM0s0bWUzKSkgICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigic2FtcGxlIikgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmlsZW5hbWUpCgpmaWxlbmFtZSA8LSBwYXN0ZShjc3ZmaWxlcGF0aCwiX3NpemVmYWN0b3JzX0gzSzI3bWUzLmNzdiIsc2VwPSJfIikKcHJpbnQoZmlsZW5hbWUpCmFzLmRhdGEuZnJhbWUoREVTZXEyOjpzaXplRmFjdG9ycyhkZHNfSDNLMjdtZTMpKSAgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJzYW1wbGUiKSAlPiUgcmVhZHI6OndyaXRlX2NzdihmaWxlbmFtZSkKCmBgYAoKdnN0ID0+IHogc2NvcmUKCmBgYHtyIHNldHVwIG1hdHJpeCBEZXNlcTIgcGFydDQgMjAwNzA3fQoKdnNkX0FUQUMgPC0gREVTZXEyOjp2c3QoZGRzX0FUQUMpICNub3JtYWxpemVkIGNvdW5044GM5YWl44Gj44Gm44GE44KL44CCKHZzdOOBi3Jsb2cpClhkX0FUQUMgPC0gU3VtbWFyaXplZEV4cGVyaW1lbnQ6OmFzc2F5KHZzZF9BVEFDKSAjIOWFqOOBpumBuOaKnigyMDAzMjYpIDIwMTkwOTIw44KS5YWD44GrICgxOTEwMjQpClhzX0FUQUMgPC0gWGRfQVRBQyAlPiUgdCAlPiUgc2NhbGUgJT4lIHQKCnZzZF9IM3AzIDwtIERFU2VxMjo6dnN0KGRkc19IM3AzKSAjbm9ybWFsaXplZCBjb3VudOOBjOWFpeOBo+OBpuOBhOOCi+OAgih2c3TjgYtybG9nKQpYZF9IM3AzIDwtIFN1bW1hcml6ZWRFeHBlcmltZW50Ojphc3NheSh2c2RfSDNwMykgIyDlhajjgabpgbjmip4oMjAwMzI2KSAyMDE5MDkyMOOCkuWFg+OBqyAoMTkxMDI0KQpYc19IM3AzIDwtIFhkX0gzcDMgJT4lIHQgJT4lIHNjYWxlICU+JSB0Cgp2c2RfSDNLMjdhYyA8LSBERVNlcTI6OnZzdChkZHNfSDNLMjdhYykgI25vcm1hbGl6ZWQgY291bnTjgYzlhaXjgaPjgabjgYTjgovjgIIodnN044GLcmxvZykKWGRfSDNLMjdhYyA8LSBTdW1tYXJpemVkRXhwZXJpbWVudDo6YXNzYXkodnNkX0gzSzI3YWMpICMg5YWo44Gm6YG45oqeKDIwMDMyNikgMjAxOTA5MjDjgpLlhYPjgasgKDE5MTAyNCkKWHNfSDNLMjdhYyA8LSBYZF9IM0syN2FjICU+JSB0ICU+JSBzY2FsZSAlPiUgdAoKdnNkX0gzSzRtZTMgPC0gREVTZXEyOjp2c3QoZGRzX0gzSzRtZTMpICNub3JtYWxpemVkIGNvdW5044GM5YWl44Gj44Gm44GE44KL44CCKHZzdOOBi3Jsb2cpClhkX0gzSzRtZTMgPC0gU3VtbWFyaXplZEV4cGVyaW1lbnQ6OmFzc2F5KHZzZF9IM0s0bWUzKSAjIOWFqOOBpumBuOaKnigyMDAzMjYpIDIwMTkwOTIw44KS5YWD44GrICgxOTEwMjQpClhzX0gzSzRtZTMgPC0gWGRfSDNLNG1lMyAlPiUgdCAlPiUgc2NhbGUgJT4lIHQKCnZzZF9IM0syN21lMyA8LSBERVNlcTI6OnZzdChkZHNfSDNLMjdtZTMpICNub3JtYWxpemVkIGNvdW5044GM5YWl44Gj44Gm44GE44KL44CCKHZzdOOBi3Jsb2cpClhkX0gzSzI3bWUzIDwtIFN1bW1hcml6ZWRFeHBlcmltZW50Ojphc3NheSh2c2RfSDNLMjdtZTMpICMg5YWo44Gm6YG45oqeKDIwMDMyNikgMjAxOTA5MjDjgpLlhYPjgasgKDE5MTAyNCkKWHNfSDNLMjdtZTMgPC0gWGRfSDNLMjdtZTMgJT4lIHQgJT4lIHNjYWxlICU+JSB0Cgp2c2R0cmFuc19BVEFDIDwtIGFzLmRhdGEuZnJhbWUoWGRfQVRBQykgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJlbnNfZ2VuZSIpICU+JSBhc190aWJibGUgJT4lIGRwbHlyOjpzZWxlY3QoImVuc19nZW5lIiwgYWxsX29mKGRlZl9saXN0X3NlbGVjdF8wJHNhbXBsZSkpCmZpbGVuYW1lIDwtIHBhc3RlKGNzdmZpbGVwYXRoLCJfdnN0cmFuc19BVEFDLmNzdiIsc2VwPSJfIikKcmVhZHI6OndyaXRlX2Nzdih2c2R0cmFuc19BVEFDLCBmaWxlbmFtZSkKbnJvdyh2c2R0cmFuc19BVEFDKQpuY29sKHZzZHRyYW5zX0FUQUMpCgp2c2R0cmFuc19IM3AzIDwtIGFzLmRhdGEuZnJhbWUoWGRfSDNwMykgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJlbnNfZ2VuZSIpICU+JSBhc190aWJibGUgJT4lIGRwbHlyOjpzZWxlY3QoImVuc19nZW5lIiwgYWxsX29mKGRlZl9saXN0X3NlbGVjdF8xJHNhbXBsZSkpCmZpbGVuYW1lIDwtIHBhc3RlKGNzdmZpbGVwYXRoLCJfdnN0cmFuc19IM3AzLmNzdiIsc2VwPSJfIikKcmVhZHI6OndyaXRlX2Nzdih2c2R0cmFuc19IM3AzLCBmaWxlbmFtZSkKbnJvdyh2c2R0cmFuc19IM3AzKQpuY29sKHZzZHRyYW5zX0gzcDMpCgp2c2R0cmFuc19IM0syN2FjIDwtIGFzLmRhdGEuZnJhbWUoWGRfSDNLMjdhYykgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJlbnNfZ2VuZSIpICU+JSBhc190aWJibGUgJT4lIGRwbHlyOjpzZWxlY3QoImVuc19nZW5lIiwgYWxsX29mKGRlZl9saXN0X3NlbGVjdF8yJHNhbXBsZSkpCmZpbGVuYW1lIDwtIHBhc3RlKGNzdmZpbGVwYXRoLCJfdnN0cmFuc19IM0syN2FjLmNzdiIsc2VwPSJfIikKcmVhZHI6OndyaXRlX2Nzdih2c2R0cmFuc19IM0syN2FjLCBmaWxlbmFtZSkKbnJvdyh2c2R0cmFuc19IM0syN2FjKQpuY29sKHZzZHRyYW5zX0gzSzI3YWMpCgp2c2R0cmFuc19IM0s0bWUzIDwtIGFzLmRhdGEuZnJhbWUoWGRfSDNLNG1lMykgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJlbnNfZ2VuZSIpICU+JSBhc190aWJibGUgJT4lIGRwbHlyOjpzZWxlY3QoImVuc19nZW5lIiwgYWxsX29mKGRlZl9saXN0X3NlbGVjdF8zJHNhbXBsZSkpCmZpbGVuYW1lIDwtIHBhc3RlKGNzdmZpbGVwYXRoLCJfdnN0cmFuc19IM0s0bWUzLmNzdiIsc2VwPSJfIikKcmVhZHI6OndyaXRlX2Nzdih2c2R0cmFuc19IM0s0bWUzLCBmaWxlbmFtZSkKbnJvdyh2c2R0cmFuc19IM0s0bWUzKQpuY29sKHZzZHRyYW5zX0gzSzRtZTMpCgp2c2R0cmFuc19IM0syN21lMyA8LSBhcy5kYXRhLmZyYW1lKFhkX0gzSzI3bWUzKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImVuc19nZW5lIikgJT4lIGFzX3RpYmJsZSAlPiUgZHBseXI6OnNlbGVjdCgiZW5zX2dlbmUiLCBhbGxfb2YoZGVmX2xpc3Rfc2VsZWN0XzQkc2FtcGxlKSkKZmlsZW5hbWUgPC0gcGFzdGUoY3N2ZmlsZXBhdGgsIl92c3RyYW5zX0gzSzI3bWUzLmNzdiIsc2VwPSJfIikKcmVhZHI6OndyaXRlX2Nzdih2c2R0cmFuc19IM0syN21lMywgZmlsZW5hbWUpCm5yb3codnNkdHJhbnNfSDNLMjdtZTMpCm5jb2wodnNkdHJhbnNfSDNLMjdtZTMpCgp6c2NvcmVfQVRBQyA8LSBYc19BVEFDICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiZW5zX2dlbmUiKSAlPiUgYXNfdGliYmxlCnpzY29yZV9IM3AzIDwtIFhzX0gzcDMgICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJlbnNfZ2VuZSIpICU+JSBhc190aWJibGUKenNjb3JlX0gzSzI3YWMgPC0gWHNfSDNLMjdhYyAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImVuc19nZW5lIikgJT4lIGFzX3RpYmJsZQp6c2NvcmVfSDNLNG1lMyA8LSBYc19IM0s0bWUzICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiZW5zX2dlbmUiKSAlPiUgYXNfdGliYmxlCnpzY29yZV9IM0syN21lMyA8LSBYc19IM0syN21lMyAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImVuc19nZW5lIikgJT4lIGFzX3RpYmJsZQoKenNjb3JlIDwtIHpzY29yZV9BVEFDICU+JSBpbm5lcl9qb2luKHpzY29yZV9IM3AzKSAlPiUgaW5uZXJfam9pbih6c2NvcmVfSDNLMjdhYykgJT4lIGlubmVyX2pvaW4oenNjb3JlX0gzSzRtZTMpICU+JSBpbm5lcl9qb2luKHpzY29yZV9IM0syN21lMykKcmVhZHI6OndyaXRlX2Nzdih6c2NvcmUsIHBhc3RlKGNzdmZpbGVwYXRoLCJfenNjb3JlX0FsbC5jc3YiLHNlcD0iXyIpKQoKenNjb3JlX3R5cGUgPC0genNjb3JlICAlPiUgaW5uZXJfam9pbihlbnNlbWJsZSkgJT4lIGRwbHlyOjpzZWxlY3QoImVuc19nZW5lIiwiZXh0X2dlbmUiLCAiYmlvdHlwZSIsImNociIsIGFsbF9vZihkZWZfbGlzdF9zZWxlY3Qkc2FtcGxlKSkKCgpgYGAKCgoKCiMjIyBub3Jt5b6M44Gu5YiG5biDCm5vcm1hbGl6ZWQgY291bnQsIHpzY29yZSDjga7liIbluIMKKDIwMTkxMDE35L+u5q2jKQoKYGBge3IgYWxsbm9ybWFsaXplZGNvdW50LCBmaWcud2lkdGg9NyxmaWcuaGVpZ2h0PTZ9Cgpub3JtX3Bsb3RsaXN0X2FsbCA8LSBub3JtYWxpemVkY291bnQgJT4lIGdhdGhlcigic2FtcGxlIiwgIm5vcm1hbGl6ZWQiLC0oZW5zX2dlbmUpKSAlPiUgaW5uZXJfam9pbihkZWZfbGlzdF9zZWxlY3QsIGJ5ID0gInNhbXBsZSIpCm5vcm1fcGxvdF9hbGwgPC0gbm9ybV9wbG90bGlzdF9hbGwgJT4lIApnZ3Bsb3QoYWVzKHRpbWVfcmVwbGljYXRlLG5vcm1hbGl6ZWQsZ3JvdXA9dGltZV9yZXBsaWNhdGUsY29sb3VyPXR5cGUpKStnZW9tX3Zpb2xpbihzY2FsZT0iY291bnQiKStnZW9tX2JveHBsb3Qod2lkdGg9LjEsKStmYWNldF93cmFwKH5zZXEqdHlwZSxuY29sPTIpK3RoZW1lX2J3KCkrIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSx2anVzdCA9IDAuNSkpICsgZ2d0aXRsZShwYXN0ZShmb2xkZXJfbmFtZSwgIihhbGwsIG5vcm1hbGl6ZWQgY291bnQpIikpICsgc2NhbGVfeV9sb2cxMChsaW1pdHMgPSBjKDAuMSxOQSkpIAoKIytnZ3NjaTo6c2NhbGVfY29sb3JfZDMoImNhdGVnb3J5MjAiKQoKcHJpbnQobm9ybV9wbG90X2FsbCkKCgoKZ2dzYXZlKHBsb3Q9bm9ybV9wbG90X2FsbCxmaWxlPSIuL05vcm1Db3VudC5wZGYiLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxNSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmBgYAoKCgojIyBRQwoKIyMjIFRvdGFsIHJlYWRzCgoyMDE5MTAxNuS/ruatoywgMjAyMDA2MjPkv67mraMKCmBgYHtyIHRvdGFsUmVhZHMsIGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9OH0KCmNocl9jaGFydCA8LSBtYXRvbWU1ICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLGNocikgJT4lIGdyb3VwX2J5KGVuc19nZW5lLGNocikgJT4lIHN1bW1hcml6ZSgpICU+JSB1bmdyb3VwKCkgCiNjaHJfY2hhcnQgPC0gYmVkZmlsZSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSxjaHIpICAlPiUgZ3JvdXBfYnkoZW5zX2dlbmUsY2hyKSAlPiUgc3VtbWFyaXplKCkgJT4lIHVuZ3JvdXAoKSAjMjAxOTEwMTbkv67mraMKCiM+IHJpZ2h0X2pvaW4oY2hyX2NoYXJ0LCBtYXRvbWU1LCBieT0iZW5zX2dlbmUiKQojIEEgdGliYmxlOiA1NSw0NTYgeCAxNAoKI2J5Y2hyPC0gbGVmdF9qb2luKG1hdG9tZTUsIGNocl9jaGFydCwgYnk9ImVuc19nZW5lIikgJT4lIGRwbHlyOjpzZWxlY3QoLShlbnNfZ2VuZSkpICU+JQojICBnYXRoZXIoInNhbXBsZSIsImNvdW50IiwtY2hyKSAlPiUKIyAgZ3JvdXBfYnkoY2hyLHNhbXBsZSkgJT4lIHN1bW1hcmlzZSh0b3RhbD1zdW0oY291bnQpKSAlPiUgdW5ncm91cAoKI21hdCA8LSBsZWZ0X2pvaW4obWF0b21lNSwgY2hyX2NoYXJ0LCBieT0iZW5zX2dlbmUiKQoKI2J5Y2hyIDwtIG1hdCAlPiUgZHBseXI6OnNlbGVjdCgtKGVuc19nZW5lKSkgJT4lCiMgIGdhdGhlcigic2FtcGxlIiwiY291bnQiLC1jaHIpICU+JQojICBncm91cF9ieShjaHIsc2FtcGxlKSAlPiUgc3VtbWFyaXNlKHRvdGFsPXN1bShjb3VudCkpICAlPiUgZl9zYW1wbGUoKSAlPiUgdW5ncm91cAoKYnljaHIgPC0gbWF0b21lNSAlPiUgZHBseXI6OnNlbGVjdChjaHIsZGVmX2xpc3Rfc2VsZWN0JHNhbXBsZSkgJT4lCiAgZ2F0aGVyKCJzYW1wbGUiLCJjb3VudCIsLWNocikgJT4lCiAgZ3JvdXBfYnkoY2hyLHNhbXBsZSkgJT4lIHN1bW1hcmlzZSh0b3RhbD1zdW0oY291bnQpKSAgJT4lIGZfc2FtcGxlKCkgJT4lIHVuZ3JvdXAKCmdncGxvdChieWNocixhZXMocmVvcmRlcihzYW1wbGUsZHBseXI6OmRlc2Moc2FtcGxlKSksdG90YWwvMWU2LGZpbGw9Y2hyKSkgKwogIHRoZW1lX2xpbmVkcmF3KCkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgY29vcmRfZmxpcCgpICsKICB4bGFiKCJzYW1wbGUiKSArIHlsYWIoIm1pbGxpb24gcmVhZHMiKSArIGdnc2NpOjpzY2FsZV9maWxsX2lndigpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IHJldihsZXZlbHMoc2FtcGxlKSkpCgoKCgpgYGAKCiMjIyBub3JtYWxpemVkIGNvdW50CgpgYGB7ciBub3JtYWxpemVkY291bnQsIGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9OH0KCm1hdF9ub3JtY291bnQgPC0gbGVmdF9qb2luKG5vcm1hbGl6ZWRjb3VudCwgY2hyX2NoYXJ0LCBieT0iZW5zX2dlbmUiKQoKYnljaHJfbWF0X25vcm1jb3VudCA8LSBtYXRfbm9ybWNvdW50ICU+JSBkcGx5cjo6c2VsZWN0KC0oZW5zX2dlbmUpKSAlPiUKICBnYXRoZXIoInNhbXBsZSIsIm5vcm1jb3VudCIsLWNocikgJT4lCiAgZ3JvdXBfYnkoY2hyLHNhbXBsZSkgJT4lIHN1bW1hcmlzZShub3JtdG90YWw9c3VtKG5vcm1jb3VudCkpICU+JSBmX3NhbXBsZSgpICU+JSB1bmdyb3VwCgpnZ3Bsb3QoYnljaHJfbWF0X25vcm1jb3VudCxhZXMocmVvcmRlcihzYW1wbGUsZHBseXI6OmRlc2Moc2FtcGxlKSksbm9ybXRvdGFsLzFlNixmaWxsPWNocikpICsKICB0aGVtZV9saW5lZHJhdygpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIGNvb3JkX2ZsaXAoKSArCiAgeGxhYigic2FtcGxlIikgKyB5bGFiKCJub3JtYWxpemVkIGNvdW50cyAobWlsbGlvbiByZWFkcykiKSArIGdnc2NpOjpzY2FsZV9maWxsX2lndigpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IHJldihsZXZlbHMoc2FtcGxlKSkpCgpgYGAKCiMjIyBDb3JyZWxhdGlvbnMKCmRyb3Agcm93cyB3aXRoIGFsbCAwIC0+ICsxLzIgLT4gZ2VvbS5zY2FsZSAtPiBsb2cgLT4gUGVhcnNvbidzCgpgYGB7ciBtYWtlbWF0LCBmaWcud2lkdGg9MTEsIGZpZy5oZWlnaHQ9MTF9CiNtYXRmX0NvcnJlbGF0aW9uIDwtIG1hdCAlPiUgZmlsdGVyKGNociE9ImNock0iKSAlPiUgZHBseXI6OnNlbGVjdCgtImNociIpICU+JSBmaWx0ZXJfYXQoLSgxKSxhbnlfdmFycyguID4gMCkpCgptYXRmX0NvcnJlbGF0aW9uIDwtIG1hdG9tZTUgJT4lIGRwbHlyOjpzZWxlY3QoY2hyLGRlZl9saXN0X3NlbGVjdCRzYW1wbGUpICU+JSBmaWx0ZXIoY2hyIT0iY2hyTSIpICU+JSBkcGx5cjo6c2VsZWN0KC0iY2hyIikgJT4lIGZpbHRlcl9hdCgtKDEpLGFueV92YXJzKC4gPiAwKSkKClhfQ29ycmVsYXRpb24gPC0gbWF0Zl9Db3JyZWxhdGlvbiAlPiUgZHBseXI6OnNlbGVjdCgtKDEpKSAlPiUgYXMubWF0cml4CnJvd25hbWVzKFhfQ29ycmVsYXRpb24pIDwtIG1hdGZfQ29ycmVsYXRpb24kZW5zX2dlbmUKbFhfQ29ycmVsYXRpb24gPC0gbG9nKGdzY2FsZShYX0NvcnJlbGF0aW9uKzAuNSkpClIgPC0gY29yKGxYX0NvcnJlbGF0aW9uKTsgZGlhZyhSKSA8LSBOQQpwaGVhdG1hcDo6cGhlYXRtYXAoUixjb2xvcj12aXJpZGlzOjp2aXJpZGlzKDI1NikpCgojWCA8LSBtYXRmICU+JSBkcGx5cjo6c2VsZWN0KC0oMTo0KSkgJT4lIGFzLm1hdHJpeAojcm93bmFtZXMoWCkgPC0gbWF0ZiRlbnNfZ2VuZQojbFggPC0gbG9nKGdzY2FsZShYKzAuNSkpCiNSIDwtIGNvcihsWCk7IGRpYWcoUikgPC0gTkEKI3BoZWF0bWFwOjpwaGVhdG1hcChSLGNvbG9yPXZpcmlkaXM6OnZpcmlkaXMoMjU2KSkKCiMjIy0tLSBERVNlcTLjgavjgojjgopub3JtYWxpemVkIGNvdW50IC0tLSMjIwojbW9kZWw8LSB+Z3JvdXAKI2Rkc19Db3JyZWxhdGlvbiA8LSBERVNlcTI6OkRFU2VxRGF0YVNldEZyb21NYXRyaXgoWF9Db3JyZWxhdGlvblssZGVmX2xpc3Rfc2VsZWN0JHNhbXBsZV0sZGVmX2xpc3Rfc2VsZWN0LG1vZGVsKSAj5b+F6KaB44Gq44K144Oz44OX44Or44Gu44G/CiNkZHNfQ29ycmVsYXRpb24gPC0gREVTZXEyOjpERVNlcURhdGFTZXRGcm9tTWF0cml4KFhfQ29ycmVsYXRpb25bLGRlZl9saXN0JHNhbXBsZV0sZGVmX2xpc3QsbW9kZWwpCiNkZHNfQ29ycmVsYXRpb24gPC0gREVTZXEyOjplc3RpbWF0ZVNpemVGYWN0b3JzKGRkc19Db3JyZWxhdGlvbikKI25vcm1fQ29ycmVsYXRpb24gPC0gREVTZXEyOjpjb3VudHMoZGRzX0NvcnJlbGF0aW9uLG5vcm1hbGl6ZWQ9VFJVRSkgI25vcm3jgatuYXJtYWxpemVkIGNvdW5044GM5YWl44KL44CCCgpgYGAKCiMjIyBEaW1lbnNpb24gcmVkdWN0aW9uCgpgYGB7ciBQQ0EsZmlnLndpZHRoPTQsZmlnLmhlaWdodD0zfQojIHNldCBzY2FsZT1UUlVFIGlmIHRoZSBwYXR0ZXJucyAobm90IGxldmVsKSBpcyB0aGUgbWF0dGVyCnAgPC0gcHJjb21wKHQobFhfQ29ycmVsYXRpb25bcmFuaygtYXBwbHkobFhfQ29ycmVsYXRpb24sMSx2YXIpKSA8PSBudG9wLF0pLHNjYWxlPXNjYWxlcm93cyxjZW50ZXI9VFJVRSkKc2NyZWVwbG90KHAsbGFzPTIsbWFpbj0iSW1wb3J0YW5jZSIpCnByaW50KHN1bW1hcnkocCkkaW1wWyxzZXEobWluKDEwLG5jb2woWF9Db3JyZWxhdGlvbikpKV0pCmBgYAoKYGBge3IgbWFrZXNjb3JlREZ9CmxhYmVsX0NvcnJlbGF0aW9uIDwtIGRlZl9saXN0X3NlbGVjdCAlPiUgZmlsdGVyKHNhbXBsZSAlaW4lIGNvbG5hbWVzKFhfQ29ycmVsYXRpb24pKQpkZiA8LSBkYXRhLmZyYW1lKHAkeCkgJT4lIGFzX3RpYmJsZShyb3duYW1lcz0ic2FtcGxlIikgJT4lCiAgaW5uZXJfam9pbihsYWJlbF9Db3JyZWxhdGlvbiwuKQoKcHJpbnQoZGYpCmBgYAoKClFDIOe1guS6hgoKIyMjIENhbGN1bGF0ZSBsb2cyIEZDCgoKCmBgYHtyIHJlc3VsdCAyZ3VuIHNldH0KCiMtLS0tLS0tIHNldHRpbmcgLS0tLS0tLSMKZmRyIDwtIDAuMSAjIGFjY2VwdGFibGUgZmFsc2UgZGlzY292ZXJ5IHJhdGUgKOWbuuWumikKbGZjdGhyZXRoIDwtIGxvZzIoMSkgIyB0aHJlc2hvbGQgaW4gYWJzKGxvZzJGQykKIyBjb250cm9scyBzaG91bGQgYmUgcGxhY2VkIGluIHRoZSByaWdodAoKcGxvdF90aXRsZTEgPC0gIjJndW4iCgoKY29udHJhc3RfSDNwMyA8LSBsaXN0KAogICNJbnRlcmNlcHQgPSBsaXN0KCJJbnRlcmNlcHQiKSwKICBncm91cF9IM3AzX1VJX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsICJIM3AzX1VJX0RveFBsdXMiLCJIM3AzX1VJX0RveE1pbnVzIiksCiAgZ3JvdXBfSDNwM18waF9Eb3hwbHVzX3ZzX21pbnVzID0gYygiZ3JvdXAiLCJIM3AzXzBoX0RveFBsdXMiLCAiSDNwM18waF9Eb3hNaW51cyIpLAogIGdyb3VwX0gzcDNfMjRoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkgzcDNfMjRoX0RveFBsdXMiLCAiSDNwM18yNGhfRG94TWludXMiKSwKICBncm91cF9IM3AzXzQ4aF9Eb3hwbHVzX3ZzX21pbnVzID0gYygiZ3JvdXAiLCJIM3AzXzQ4aF9Eb3hQbHVzIiwgIkgzcDNfNDhoX0RveE1pbnVzIikKKQoKCgpjb250cmFzdF9IM0s0bWUzIDwtIGxpc3QoCiAgI0ludGVyY2VwdCA9IGxpc3QoIkludGVyY2VwdCIpLAogIGdyb3VwX0gzSzRtZTNfVUlfRG94cGx1c192c19taW51cyA9IGMoImdyb3VwIiwgIkgzSzRtZTNfVUlfRG94UGx1cyIsIkgzSzRtZTNfVUlfRG94TWludXMiKSwKICBncm91cF9IM0s0bWUzXzBoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkgzSzRtZTNfMGhfRG94UGx1cyIsICJIM0s0bWUzXzBoX0RveE1pbnVzIiksCiAgZ3JvdXBfSDNLNG1lM18yNGhfRG94cGx1c192c19taW51cyA9IGMoImdyb3VwIiwiSDNLNG1lM18yNGhfRG94UGx1cyIsICJIM0s0bWUzXzI0aF9Eb3hNaW51cyIpLAogIGdyb3VwX0gzSzRtZTNfNDhoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkgzSzRtZTNfNDhoX0RveFBsdXMiLCAiSDNLNG1lM180OGhfRG94TWludXMiKQopCgpjb250cmFzdF9IM0syN2FjIDwtIGxpc3QoCiAgI0ludGVyY2VwdCA9IGxpc3QoIkludGVyY2VwdCIpLAogIGdyb3VwX0gzSzI3YWNfVUlfRG94cGx1c192c19taW51cyA9IGMoImdyb3VwIiwgIkgzSzI3YWNfVUlfRG94UGx1cyIsIkgzSzI3YWNfVUlfRG94TWludXMiKSwKICBncm91cF9IM0syN2FjXzBoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkgzSzI3YWNfMGhfRG94UGx1cyIsICJIM0syN2FjXzBoX0RveE1pbnVzIiksCiAgZ3JvdXBfSDNLMjdhY18yNGhfRG94cGx1c192c19taW51cyA9IGMoImdyb3VwIiwiSDNLMjdhY18yNGhfRG94UGx1cyIsICJIM0syN2FjXzI0aF9Eb3hNaW51cyIpLAogIGdyb3VwX0gzSzI3YWNfNDhoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkgzSzI3YWNfNDhoX0RveFBsdXMiLCAiSDNLMjdhY180OGhfRG94TWludXMiKQopCgoKY29udHJhc3RfSDNLMjdtZTMgPC0gbGlzdCgKICAjSW50ZXJjZXB0ID0gbGlzdCgiSW50ZXJjZXB0IiksCiAgZ3JvdXBfSDNLMjdtZTNfVUlfRG94cGx1c192c19taW51cyA9IGMoImdyb3VwIiwgIkgzSzI3bWUzX1VJX0RveFBsdXMiLCJIM0syN21lM19VSV9Eb3hNaW51cyIpLAogIGdyb3VwX0gzSzI3bWUzXzBoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkgzSzI3bWUzXzBoX0RveFBsdXMiLCAiSDNLMjdtZTNfMGhfRG94TWludXMiKSwKICBncm91cF9IM0syN21lM18yNGhfRG94cGx1c192c19taW51cyA9IGMoImdyb3VwIiwiSDNLMjdtZTNfMjRoX0RveFBsdXMiLCAiSDNLMjdtZTNfMjRoX0RveE1pbnVzIiksCiAgZ3JvdXBfSDNLMjdtZTNfNDhoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkgzSzI3bWUzXzQ4aF9Eb3hQbHVzIiwgIkgzSzI3bWUzXzQ4aF9Eb3hNaW51cyIpCikKCmNvbnRyYXN0X0FUQUMgPC0gbGlzdCgKICAjSW50ZXJjZXB0ID0gbGlzdCgiSW50ZXJjZXB0IiksCiAgZ3JvdXBfQVRBQ19VSV9Eb3hwbHVzX3ZzX21pbnVzID0gYygiZ3JvdXAiLCAiQVRBQ19VSV9Eb3hQbHVzIiwiQVRBQ19VSV9Eb3hNaW51cyIpLAogIGdyb3VwX0FUQUNfNDhoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsIkFUQUNfNDhoX0RveFBsdXMiLCAiQVRBQ180OGhfRG94TWludXMiKQopCgojIEJSQgojICBncm91cF9VSV9Eb3hwbHVzX3ZzX21pbnVzID0gYygiZ3JvdXAiLCAiQlJCX1VJX0RveFBsdXMiLCAiQlJCX1VJX0RveE1pbnVzIiksCiMgIGdyb3VwXzBoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsICJCUkJfMGhfRG94UGx1cyIsICJCUkJfMGhfRG94TWludXMiKSwKIyAgZ3JvdXBfMjRoX0RveHBsdXNfdnNfbWludXMgPSBjKCJncm91cCIsICJCUkJfMjRoX0RveFBsdXMiLCAiQlJCXzI0aF9Eb3hNaW51cyIpLAojICBncm91cF80OGhfRG94cGx1c192c19taW51cyA9IGMoImdyb3VwIiwgIkJSQl80OGhfRG94UGx1cyIsICJCUkJfNDhoX0RveE1pbnVzIikKICAKCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jCgojLS0tLS0tLS0tLS0tLS0g6Ieq5YuVIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwojLS0g44OV44Kh44Kk44Or5ZCNIOOBruioreWumiAtLS0jCiNmb2xkZXJfbmFtZV9wbG90MCA8LSBwYXN0ZSgiLiIsZm9sZGVyX25hbWUsIHBhc3RlKGZvbGRlcl9uYW1lLHBsb3RfdGl0bGUxLHNlcD0iXyIpLCIiLHNlcD0iLyIpCiNmb2xkZXJfbmFtZV9wbG90X3BhdGggPC0gcGFzdGUoZm9sZGVyX25hbWVfcGxvdDAscGFzdGUoZm9sZGVyX25hbWUscGxvdF90aXRsZTEsIiIsc2VwPSJfIiksc2VwPSIiKQoKYGBgCgoKbG9nMiBGQyDjga7jgb/oqIjnrpcgKERFR+OBr+eJueOBq+WHuuOBleOBquOBhCkKCmBgYHtyIGV4dHJhY3RSZXN9CgoKcmVzX0gzcDMgPC0gbWFwcGx5KGZ1bmN0aW9uKHgpCiAgREVTZXEyOjpyZXN1bHRzKGRkc19IM3AzLHgsbGZjVGhyZXNob2xkPWxmY3RocmV0aCxhbHBoYT1mZHIpCixjb250cmFzdF9IM3AzKQoKcmVzX0gzSzRtZTMgPC0gbWFwcGx5KGZ1bmN0aW9uKHgpCiAgREVTZXEyOjpyZXN1bHRzKGRkc19IM0s0bWUzLHgsbGZjVGhyZXNob2xkPWxmY3RocmV0aCxhbHBoYT1mZHIpCixjb250cmFzdF9IM0s0bWUzKQoKcmVzX0gzSzI3YWMgPC0gbWFwcGx5KGZ1bmN0aW9uKHgpCiAgREVTZXEyOjpyZXN1bHRzKGRkc19IM0syN2FjLHgsbGZjVGhyZXNob2xkPWxmY3RocmV0aCxhbHBoYT1mZHIpCixjb250cmFzdF9IM0syN2FjKQoKCnJlc19IM0syN21lMyA8LSBtYXBwbHkoZnVuY3Rpb24oeCkKICBERVNlcTI6OnJlc3VsdHMoZGRzX0gzSzI3bWUzLHgsbGZjVGhyZXNob2xkPWxmY3RocmV0aCxhbHBoYT1mZHIpCixjb250cmFzdF9IM0syN21lMykKCgpyZXNfQVRBQyA8LSBtYXBwbHkoZnVuY3Rpb24oeCkKICBERVNlcTI6OnJlc3VsdHMoZGRzX0FUQUMseCxsZmNUaHJlc2hvbGQ9bGZjdGhyZXRoLGFscGhhPWZkcikKLGNvbnRyYXN0X0FUQUMpCgoKCnByaW50KGZkcikKCmBgYAoKYGBge3IgZXh0cmFjdFJlczJ9CgpyZV9IM3AzX2FsbCA8LSBtYXAocmVzX0gzcDMsYXNfdGliYmxlLHJvd25hbWVzPSJlbnNfZ2VuZSIpICU+JQogIHRpYmJsZShhc3BlY3Q9ZmFjdG9yKG5hbWVzKC4pLG5hbWVzKC4pKSxkYXRhPS4pICU+JQogIG11dGF0ZShkYXRhPW1hcChkYXRhLGFubm90YXRlKSkgJT4lCiAgdW5uZXN0KGNvbHMgPSAiZGF0YSIpCgpyZV9IM0s0bWUzX2FsbCA8LSBtYXAocmVzX0gzSzRtZTMsYXNfdGliYmxlLHJvd25hbWVzPSJlbnNfZ2VuZSIpICU+JQogIHRpYmJsZShhc3BlY3Q9ZmFjdG9yKG5hbWVzKC4pLG5hbWVzKC4pKSxkYXRhPS4pICU+JQogIG11dGF0ZShkYXRhPW1hcChkYXRhLGFubm90YXRlKSkgJT4lCiAgdW5uZXN0KGNvbHMgPSAiZGF0YSIpCgpyZV9IM0syN2FjX2FsbCA8LSBtYXAocmVzX0gzSzI3YWMsYXNfdGliYmxlLHJvd25hbWVzPSJlbnNfZ2VuZSIpICU+JQogIHRpYmJsZShhc3BlY3Q9ZmFjdG9yKG5hbWVzKC4pLG5hbWVzKC4pKSxkYXRhPS4pICU+JQogIG11dGF0ZShkYXRhPW1hcChkYXRhLGFubm90YXRlKSkgJT4lCiAgdW5uZXN0KGNvbHMgPSAiZGF0YSIpCgpyZV9IM0syN21lM19hbGwgPC0gbWFwKHJlc19IM0syN21lMyxhc190aWJibGUscm93bmFtZXM9ImVuc19nZW5lIikgJT4lCiAgdGliYmxlKGFzcGVjdD1mYWN0b3IobmFtZXMoLiksbmFtZXMoLikpLGRhdGE9LikgJT4lCiAgbXV0YXRlKGRhdGE9bWFwKGRhdGEsYW5ub3RhdGUpKSAlPiUKICB1bm5lc3QoY29scyA9ICJkYXRhIikKCnJlX0FUQUNfYWxsIDwtIG1hcChyZXNfQVRBQyxhc190aWJibGUscm93bmFtZXM9ImVuc19nZW5lIikgJT4lCiAgdGliYmxlKGFzcGVjdD1mYWN0b3IobmFtZXMoLiksbmFtZXMoLikpLGRhdGE9LikgJT4lCiAgbXV0YXRlKGRhdGE9bWFwKGRhdGEsYW5ub3RhdGUpKSAlPiUKICB1bm5lc3QoY29scyA9ICJkYXRhIikKCgpmaWxlbmFtZSA8LSBwYXN0ZSgiLi8yZ3VuLyIsY3N2ZmlsZXBhdGgsIl9yZXN1bHRzYWxsX2ZkcjBwMV9IM3AzLmNzdiIsc2VwPSIiKQpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2NzdihyZV9IM3AzX2FsbCxmaWxlbmFtZSkKbnJvdyhyZV9IM3AzX2FsbCkKCmZpbGVuYW1lIDwtIHBhc3RlKCIuLzJndW4vIixjc3ZmaWxlcGF0aCwiX3Jlc3VsdHNhbGxfZmRyMHAxX0gzSzRtZTMuY3N2IixzZXA9IiIpCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KHJlX0gzSzRtZTNfYWxsLGZpbGVuYW1lKQpucm93KHJlX0gzSzRtZTNfYWxsKQoKZmlsZW5hbWUgPC0gcGFzdGUoIi4vMmd1bi8iLGNzdmZpbGVwYXRoLCJfcmVzdWx0c2FsbF9mZHIwcDFfSDNLMjdhYy5jc3YiLHNlcD0iIikKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3YocmVfSDNLMjdhY19hbGwsZmlsZW5hbWUpCm5yb3cocmVfSDNLMjdhY19hbGwpCgpmaWxlbmFtZSA8LSBwYXN0ZSgiLi8yZ3VuLyIsY3N2ZmlsZXBhdGgsIl9yZXN1bHRzYWxsX2ZkcjBwMV9IM0syN21lMy5jc3YiLHNlcD0iIikKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3YocmVfSDNLMjdtZTNfYWxsLGZpbGVuYW1lKQpucm93KHJlX0gzSzI3bWUzX2FsbCkKCmZpbGVuYW1lIDwtIHBhc3RlKCIuLzJndW4vIixjc3ZmaWxlcGF0aCwiX3Jlc3VsdHNhbGxfZmRyMHAxX0FUQUMuY3N2IixzZXA9IiIpCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KHJlX0FUQUNfYWxsLGZpbGVuYW1lKQpucm93KHJlX0FUQUNfYWxsKQoKYGBgCgoKCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBDbHVzdGVyaW5nIChhbGwgZ2VuZXMpCgpjbHVzdGVyaW5nIEgzLjMKCmBgYHtyIGNsdXN0ZXJpbmcgSDNwMyBhbGwgZ2VuZXMga2VtYW5zNCwgZmlnLndpZHRoPTYsZmlnLmhlaWdodD01fQojMjAxOTEyMDXkv67mraPjgajkvZzmiJAKCgoKY2x1c3Rlcl9udW1iZXIgPC0gNgoKCiMjLS0tLS0tLS0tIGNsdXN0ZXJpbmcgLS0tLS0tLS0tLS0jCnNldC5zZWVkKDMpCgojIEgzLjPjgacKIAp6c2NvcmVfSDNwM19zIDwtIHpzY29yZV90eXBlICU+JSBkcGx5cjo6c2VsZWN0KCJlbnNfZ2VuZSIsYWxsX29mKGRlZl9saXN0X3NlbGVjdF8xJHNhbXBsZSkpICAlPiUgZmlsdGVyKGFjcm9zcyh3aGVyZShpc19kb3VibGUpLCB+ICgueCAhPSAwKXwoLnggPT0gMCkpKQojenNjb3JlX0gzcDNfcyA8LSB6c2NvcmVfSDNwMyAlPiUgZmlsdGVyKGFjcm9zcyh3aGVyZShpc19kb3VibGUpLCB+ICgueCAhPSAwKXwoLnggPT0gMCkpKQoKbnJvdyh6c2NvcmVfdHlwZSkKbnJvdyh6c2NvcmVfSDNwM19zKQoKWHNfSDNwMyA8LSB6c2NvcmVfSDNwM19zICU+JSBkcGx5cjo6c2VsZWN0KC1lbnNfZ2VuZSkgJT4lIGFzLm1hdHJpeCgpCnJvd25hbWVzKFhzX0gzcDMpIDwtIHpzY29yZV9IM3AzX3MkZW5zX2dlbmUKCmttX2FsbEgzcDMgPC0ga21lYW5zKFhzX0gzcDMsY2x1c3Rlcl9udW1iZXIsbnN0YXJ0ID0gMjUsYWxnb3JpdGhtID0gIkxsb3lkIikKa21jX2FsbEgzcDMgPC0ga21fYWxsSDNwMyRjZW50ZXJzICU+JSBhc190aWJibGUocm93bmFtZXM9ImNsdXN0ZXIiKSAlPiUgZ2F0aGVyKHNhbXBsZSx2YWwsLWNsdXN0ZXIpICU+JSBpbm5lcl9qb2luKGRlZl9saXN0X3NlbGVjdCkKCmttY19hbGxIM3AzX2dyb3VwIDwtIGttY19hbGxIM3AzCgoja21jX0xSVF9ncm91cCA8LSBrbWNfTFJUICU+JSBtdXRhdGUoZ3Jvd3RoPWZhY3Rvcihncm93dGgsIGMoIlVJIiwiRGlmZjBoIiwiRGlmZjI0aCIsIkRpZmY0OGgiKSkpICU+JSBtdXRhdGUodHlwZT1mYWN0b3IodHlwZSwgYygiRG94cGx1cyIsIkRveG1pbnVzIikpKQoKI2ttY19MUlRfZ3JvdXAgPC0ga21jX0xSVF9ncm91cCAlPiUgbXV0YXRlKHRpbWU9Y2FzZV93aGVuKGdyb3d0aD09IlVJIiB+IlVJIixncm93dGg9PSJEaWZmMGgifiIwaCIsZ3Jvd3RoPT0iRGlmZjI0aCJ+IjI0aCIsZ3Jvd3RoPT0iRGlmZjQ4aCJ+IjQ4aCIsVFJVRX4iZXJyb3IiKSkKI2ttY19MUlRfZ3JvdXAgPC0ga21jX0xSVF9ncm91cCAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwiMGgiLCIyNGgiLCI0OGgiKSkpCgojZ2dnZ2xhYmVsIDwtIHBhc3RlKCJrLW1lYW5zOiBUb3RhbCIsbnJvdyhYc19IM3AzKSwiWzFdIixrbV9hbGxIM3AzJHNpemVbMV0sIlsyXSIsa21fYWxsSDNwMyRzaXplWzJdLCJbM10iLGttX2FsbEgzcDMkc2l6ZVszXSwiWzRdIixrbV9hbGxIM3AzJHNpemVbNF0sIls1XSIsa21fYWxsSDNwMyRzaXplWzVdLCJbNl0iLGttX2FsbEgzcDMkc2l6ZVs2XSxzZXA9IiAiKQoKZ2dnZ2xhYmVsIDwtIHBhc3RlKCJPcmlnaW5hbCIsbnJvdyh6c2NvcmVfdHlwZSksIkgzLjMgay1tZWFuczogVG90YWwiLG5yb3coWHNfSDNwMyksIlsxXSIsa21fYWxsSDNwMyRzaXplWzFdLCJbMl0iLGttX2FsbEgzcDMkc2l6ZVsyXSwiWzNdIixrbV9hbGxIM3AzJHNpemVbM10sIls0XSIsa21fYWxsSDNwMyRzaXplWzRdLCJbNV0iLGttX2FsbEgzcDMkc2l6ZVs1XSwiWzZdIixrbV9hbGxIM3AzJHNpemVbNl0sc2VwPSIgIikKCiMtLS0tLS0tIHNpemUgLS0tLS0tLSMKCnByaW50KGttX2FsbEgzcDMkc2l6ZSkgCiNycnJlc19hbGxIM3AzIDwtIGttX2FsbEgzcDMkY2x1c3RlciAlPiUgdGliYmxlKGVuc19nZW5lPW5hbWVzKC4pLGNsdXN0ZXI9LikgJT4lIGxlZnRfam9pbih6c2NvcmVfdHlwZV9jbHVzMywuKSAlPiUgYXJyYW5nZShjbHVzdGVyKSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSxleHRfZ2VuZSxiaW90eXBlLGNocixjbHVzdGVyLGFsbF9vZihkZWZfbGlzdF9zZWxlY3Qkc2FtcGxlKSkKCnJycmVzX2FsbEgzcDMgPC0ga21fYWxsSDNwMyRjbHVzdGVyICU+JSB0aWJibGUoZW5zX2dlbmU9bmFtZXMoLiksY2x1c3Rlcj0uKSAlPiUgbGVmdF9qb2luKC4senNjb3JlX3R5cGUpICU+JSBhcnJhbmdlKGNsdXN0ZXIpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLGV4dF9nZW5lLGJpb3R5cGUsY2hyLGNsdXN0ZXIsYWxsX29mKGRlZl9saXN0X3NlbGVjdCRzYW1wbGUpKQoKI3JycmVzX2FsbEgzcDMgPC0ga21fYWxsSDNwMyRjbHVzdGVyICU+JSB0aWJibGUoZW5zX2dlbmU9bmFtZXMoLiksY2x1c3Rlcj0uKSAlPiUgbGVmdF9qb2luKHpzY29yZV90eXBlLC4pICU+JSBhcnJhbmdlKGNsdXN0ZXIpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLGV4dF9nZW5lLGJpb3R5cGUsY2hyLGNsdXN0ZXIsYWxsX29mKGRlZl9saXN0X3NlbGVjdCRzYW1wbGUpKQoKI3JycmVzX0xSVCA8LSBrbV9MUlQkY2x1c3RlciAlPiUgdGliYmxlKGVuc19nZW5lPW5hbWVzKC4pLGNsdXN0ZXI9LikgJT4lIHJpZ2h0X2pvaW4oZTJnLC4pICU+JSBhcnJhbmdlKGNsdXN0ZXIpCgpmaWxlX3BhdGggPC0gcGFzdGUoIi4vSDNwM2FsbGNsdXN0ZXIvIiwgY3N2ZmlsZXBhdGgsICJfa21lYW5zX2NsdXN0ZXIuY3N2IixzZXA9IiIpIApyZWFkcjo6d3JpdGVfY3N2KHJycmVzX2FsbEgzcDMsZmlsZV9wYXRoKQoKIyMtLS0tLS0tIFBDQSAtLS0tLS0tIwoKcGNhY2x1c3Rlcl9zYXZlIDwtIHByY29tcChYc19IM3AzKSR4ICU+JSBhc190aWJibGUgJT4lIGRwbHlyOjpzZWxlY3QoUEMxLFBDMikgJT4lIG11dGF0ZShjbHVzdGVyPWttX2FsbEgzcDMkY2x1c3RlcikgJT4lIGdncGxvdChhZXMoUEMxLFBDMixjb2xvdXI9ZmFjdG9yKGNsdXN0ZXIpKSkrZ2VvbV9wb2ludChzaXplPTEuNSxhbHBoYT0wLjYpK2Nvb3JkX2ZpeGVkKCkrdGhlbWVfbGluZWRyYXcoKStnZ3NjaTo6c2NhbGVfY29sb3JfZDMoImNhdGVnb3J5MjAiKQoKZmlsZV9wYXRoIDwtIHBhc3RlKCIuL0gzcDNhbGxjbHVzdGVyLyIsIGNzdmZpbGVwYXRoLCAiX2ttZWFuc19fcGNhY2x1c3Rlcl9QQzFQQzIucGRmIixzZXA9IiIpIApnZ3NhdmUocGxvdD1wY2FjbHVzdGVyX3NhdmUsZmlsZT1maWxlX3BhdGgsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIGRwaSA9IDEyMCkKcHJpbnQocGNhY2x1c3Rlcl9zYXZlKQoKcGNhY2x1c3Rlcl9zYXZlIDwtIHByY29tcChYc19IM3AzKSR4ICU+JSBhc190aWJibGUgJT4lIGRwbHlyOjpzZWxlY3QoUEMxLFBDMykgJT4lIG11dGF0ZShjbHVzdGVyPWttX2FsbEgzcDMkY2x1c3RlcikgJT4lIGdncGxvdChhZXMoUEMxLFBDMyxjb2xvdXI9ZmFjdG9yKGNsdXN0ZXIpKSkrZ2VvbV9wb2ludChzaXplPTEuNSxhbHBoYT0wLjYpK2Nvb3JkX2ZpeGVkKCkrdGhlbWVfbGluZWRyYXcoKStnZ3NjaTo6c2NhbGVfY29sb3JfZDMoImNhdGVnb3J5MjAiKQoKZmlsZV9wYXRoIDwtIHBhc3RlKCIuL0gzcDNhbGxjbHVzdGVyLyIsIGNzdmZpbGVwYXRoLCAiX2ttZWFuc19fcGNhY2x1c3Rlcl9QQzFQQzMucGRmIixzZXA9IiIpIApnZ3NhdmUocGxvdD1wY2FjbHVzdGVyX3NhdmUsZmlsZT1maWxlX3BhdGgsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIGRwaSA9IDEyMCkKcHJpbnQocGNhY2x1c3Rlcl9zYXZlKQoKCiM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0jCiMgbW91c2VDVFggMDQzOOOCkuWPguiAg+OBq+OAggoKIy0tLS0tLS0tLS0tLS0tLS0tLSMKZl9jbHVzdGVyIDwtIGZ1bmN0aW9uKHgpIHggJT4lIGdyb3VwX2J5KGdyb3VwLCB0eXBlLCB0aW1lLCBjbHVzdGVyLCBzZXEpICU+JSBzdW1tYXJpc2UoYXZnPW1lYW4odmFsKSxzZT1zZCh2YWwpL3NxcnQobGVuZ3RoKHZhbCkpKSAlPiUgdW5ncm91cCgpCnByaW50KGttY19hbGxIM3AzX2dyb3VwICU+JSBncm91cF9ieShncm91cCwgdHlwZSwgdGltZSkgJT4lIHN1bW1hcmlzZSgpKQoKZl9jbHVzdGVycCA8LSBmdW5jdGlvbih4KSB4ICU+JSBncm91cF9ieShncm91cCwgdHlwZSwgdGltZSwgY2x1c3Rlciwgc2VwKSAlPiUgc3VtbWFyaXNlKGF2Zz1tZWFuKHZhbCksc2U9c2QodmFsKS9zcXJ0KGxlbmd0aCh2YWwpKSkgJT4lIHVuZ3JvdXAoKQpwcmludChrbWNfYWxsSDNwM19ncm91cCAlPiUgZ3JvdXBfYnkoZ3JvdXAsIHR5cGUsIHRpbWUpICU+JSBzdW1tYXJpc2UoKSkgI+S9nOWbs+eUqAoKIy0tLS0tLS0jCgpjbHVzdGVyX3NhdmUgPC0ga21jX2FsbEgzcDNfZ3JvdXAgJT4lCmdncGxvdChhZXModGltZSx2YWwsZ3JvdXA9dHlwZSxjb2xvdXI9dHlwZSkpKyBnZW9tX2FibGluZShpbnRlcmNlcHQ9MCxzbG9wZT0wLGxpbmV0eXBlPSJkYXNoZWQiLGNvbG91cj0iZ3JheSIpICtnZW9tX2xpbmUoYWVzKHg9dGltZSx5PWF2Zyxjb2xvdXI9dHlwZSksZGF0YT1mX2NsdXN0ZXIpK2dlb21fcG9pbnQoKStmYWNldF93cmFwKH5jbHVzdGVyKnNlcSxuY29sPTMpK2dnc2NpOjpzY2FsZV9jb2xvcl9ucGcoKSt0aGVtZV9idygpKyB0aGVtZShzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQodmp1c3QgPSAwLjUpLCBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT01KSkgICsgZ2d0aXRsZShnZ2dnbGFiZWwpK2dnc2NpOjpzY2FsZV9jb2xvcl9ucGcoKSAgKyB5bGFiKCJ6IHNjb3JlIikKCgoKZmlsZV9wYXRoIDwtIHBhc3RlKCIuL0gzcDNhbGxjbHVzdGVyLyIsIGNzdmZpbGVwYXRoLCAiX2NsdXN0ZXJfdHlwZS5wZGYiLHNlcD0iIikgCmdnc2F2ZShwbG90PWNsdXN0ZXJfc2F2ZSxmaWxlPWZpbGVfcGF0aCwgd2lkdGggPSA2LCBoZWlnaHQgPSA2LCBkcGkgPSAxMjApCiNnZ3NhdmUocGxvdD1jbHVzdGVyX3NhdmUsZmlsZT1maWxlX3BhdGgsIHdpZHRoID0gNiwgaGVpZ2h0ID0gNiwgZHBpID0gMTIwKQpwcmludChjbHVzdGVyX3NhdmUpCgojPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IwoKCgpgYGAKCmBgYHtyIHNlcSBIM3AzIGNsdXN0ZXJ9CnpfSDNwM2NsdXMxIDwtIHJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcihjbHVzdGVyPT0iMSIpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzPWNsdXN0ZXIpCnpfSDNwM2NsdXMyIDwtIHJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcihjbHVzdGVyPT0iMiIpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzPWNsdXN0ZXIpCnpfSDNwM2NsdXMzIDwtIHJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcihjbHVzdGVyPT0iMyIpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzPWNsdXN0ZXIpCnpfSDNwM2NsdXM0IDwtIHJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcihjbHVzdGVyPT0iNCIpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzPWNsdXN0ZXIpCnpfSDNwM2NsdXM1IDwtIHJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcihjbHVzdGVyPT0iNSIpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzPWNsdXN0ZXIpCnpfSDNwM2NsdXM2IDwtIHJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcihjbHVzdGVyPT0iNiIpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzPWNsdXN0ZXIpCgpucm93KHJycmVzX2FsbEgzcDMpCm5yb3coel9IM3AzY2x1czEpCm5yb3coel9IM3AzY2x1czIpCm5yb3coel9IM3AzY2x1czMpCm5yb3coel9IM3AzY2x1czQpCm5yb3coel9IM3AzY2x1czUpCm5yb3coel9IM3AzY2x1czYpCm5yb3cocnJyZXNfYWxsSDNwMyAlPiUgZmlsdGVyKGlzLm5hKGNsdXN0ZXIpKSkKCnJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcihleHRfZ2VuZSAlaW4lIGMoIk15aDMiLCJDa20iLCJBY3RhMSIsIlRubnQyIiwiQWN0YiIsIkNzcnAzIiwiVHBtMiIsIk5zZGhsIiwiTXlvZyIpKQpgYGAKCgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi0tLS0tLS0tCiMjIEJSQiByZXN1bHQKCgpgYGB7ciBCUkIgcmVzdWx0IGV4dH0KCmNsdXN0ZXJfbnVtIDwtIDQgCgojIy0tLS0gQlJC44Gu44Kv44Op44K544K/44Oq44Oz44KwKExSVCkg44Gu57WQ5p6cIC0tLS0tLS0jCiNmaWxlcGF0aF9CUkJjbHVzdGVyIDwtICIvaG9tZS9ndWVzdEEvbzcwNTc4YS9ha3V3YWthZG8va3V3YWthZG8vQlJCU2VxL0gzbW0xOF9Eb3hfMDQzMmxhbmUyL0ZpbmFsX1JzZXJ2ZXJfMTkxMjAzL0xSVC9ERUdfZmRyMHAxX19CUkIwNDMybGFuZTJub3VtaV9IM21tMThfRG94X2ttZWFuczRfX2NsdXN0ZXJfcmVzdWx0LmNzdiIgI0JSQuetieOBrkRFR+OBruODquOCueODiAojZmlsZXBhdGhfQlJCYWxsZ2VuZSA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9Sc2VydmVyXzE5MTIwMy9IM21tMThLT18zVDNfRG94X25vcm1Db3VudF9nZW5lbmFtZS5jc3YiICNCUkLnrYnjga5ERUfjga7jg6rjgrnjg4gKI2ZpbGVwYXRoX0JSQnpzY29yZSA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9Sc2VydmVyXzE5MTIwMy9MUlQvY2x1c3RlcmluZ19Yc0xSVGFsbF9fQlJCMDQzMmxhbmUybm91bWlfSDNtbTE4X0RveC5jc3YiCiNmaWxlcGF0aF9CUkJkZWYgPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9CUkJTZXEvSDNtbTE4X0RveF8wNDMybGFuZTIvRmluYWxfUnNlcnZlcl8xOTEyMDMvZGVmdGFibGVfQlJCX25vdW1pX25ld18xOTA1MjBfZmluMTkxMjA1dmVyLnR4dCIKI2ZpbGVwYXRoX0JSQmRlZiA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0NoSUxTZXEyL0tvbWF0c3VfM1QzX0VHRlBfSDNtbTE4X0RveF9jaElsXzAxMTFOT1ZBc2VxL1RTU19jb3VudC9DaElMQWxsX1RTU19wbTVrYl93aXRoQVRBQy9kZWZ0YWJsZV9CUkJfbm91bWlfbmV3XzE5MDUyMF9maW4xOTEyMDV2ZXJfMjAyMDA2MjUudHh0IgojZmlsZXBhdGhfQlJCQ2hJTEFUQUNfZGVmIDwtICIvaG9tZS9ndWVzdEEvbzcwNTc4YS9ha3V3YWthZG8va3V3YWthZG8vQ2hJTFNlcTIvS29tYXRzdV8zVDNfRUdGUF9IM21tMThfRG94X2NoSWxfMDExMU5PVkFzZXEvVFNTX2NvdW50L0NoSUxBbGxfVFNTX3BtNWtiX3dpdGhBVEFDL2RlZnRhYmxlX211bHRpY292X0NoSUwwMTEwMDExMV8yMDIwMDUwMV8zVDNfRUdGUDE4X1VJX0RveE1pbnVzX0gzcDNLMjdhY0s0S21lMzI3bWUzX3dpdGhBVEFDX3dpdGhCUkIudHh0IgojZmlsZXBhdGhfQlJCZW5zZW1ibGUgPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9CUkJTZXEvSDNtbTE4X0RveF8wNDMybGFuZTIvRmluYWxfUnNlcnZlcl8xOTEyMDMvZW5zZW1ibGVfbGlzdF9hc2lhLmNzdiIgI0JSQuOBruaZguOBrmdlbmXlkI3jg6rjgrnjg4gKI2ZpbGVwYXRoX0JSQl9GQ19hbGwgPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9CUkJTZXEvSDNtbTE4X0RveF8wNDMybGFuZTIvRmluYWxfUnNlcnZlcl8xOTEyMDMvTFJUL2FsbF9fQlJCMDQzMmxhbmUybm91bWlfSDNtbTE4X0RveC5jc3YiICNCUkLnrYnjga5ERUfjga7jg6rjgrnjg4gKI2ZpbGVwYXRoX0JSQl8yZ3VuIDwtICIvaG9tZS9ndWVzdEEvbzcwNTc4YS9ha3V3YWthZG8va3V3YWthZG8vQlJCU2VxL0gzbW0xOF9Eb3hfMDQzMmxhbmUyL0ZpbmFsX1JzZXJ2ZXJfMTkxMjAzLzJndW4vQlJCMDQzMmxhbmUybm91bWlfSDNtbTE4X0RveF9yZXN1bHRzX2ZkcjBwMV9fZmluYWwxOTEyMDUuY3N2IiAjQlJC562J44GuREVH44Gu44Oq44K544OICgpmaWxlcGF0aF9CUkJkZWYgPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9CUkJTZXEvSDNtbTE4X0RveF8wNDMybGFuZTIvRmluYWxfTGFzdF9Sc2VydmVyXzIwMDgxMS9kZWZ0YWJsZV9CUkJfbm91bWlfbmV3XzE5MDUyMF9MYXN0MjAyMDA4MTF2ZXIudHh0IgoKZmlsZXBhdGhfQlJCY2x1c3RlciA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9MYXN0X1JzZXJ2ZXJfMjAwODExL0xSVC9ERUdfZmRyMHAxX19CUkIwNDMybGFuZTJub3VtaV9IM21tMThfRG94X2ttZWFuczRfX2NsdXN0ZXJfcmVzdWx0LmNzdiIgI0JSQuetieOBrkRFR+OBruODquOCueODiAoKZmlsZXBhdGhfQlJCYWxsZ2VuZSA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9MYXN0X1JzZXJ2ZXJfMjAwODExL0gzbW0xOEtPXzNUM19Eb3hfbm9ybUNvdW50X2dlbmVuYW1lLmNzdiIgI0JSQuetieOBrkRFR+OBruODquOCueODiApmaWxlcGF0aF9CUkJ6c2NvcmUgPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9CUkJTZXEvSDNtbTE4X0RveF8wNDMybGFuZTIvRmluYWxfTGFzdF9Sc2VydmVyXzIwMDgxMS9IM21tMThLT18zVDNfRG94X196c2NvcmVfdHlwZV9hbGwuY3N2IgoKCiMjMjAyMDA4MTEgbG9nMkZDCmZpbGVwYXRoX0JSQl9GQ19kZXNlcSA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9MYXN0X1JzZXJ2ZXJfMjAwODExLzJndW4vQlJCMDQzMmxhbmUybm91bWlfSDNtbTE4X0RveF9yZXN1bHRzYWxsX2ZkcjBwMV9fZmluYWwxOTEyMDVfbGFzdDIwMDgxMS5jc3YiICNCUkLnrYnjga5ERUfjga7jg6rjgrnjg4gKZmlsZXBhdGhfQlJCX25vcm1jb3VudCA8LSAiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9MYXN0X1JzZXJ2ZXJfMjAwODExL0JSQjA0MzJsYW5lMm5vdW1pX0gzbW0xOF9Eb3hfX25vcm1Db3VudF9fZmluYWwxOTEyMDVfbGFzdDIwMDgxMS5jc3YiCgoKI2ZpbGVwYXRoX0JSQl9ub3JtY291bnQgPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9CUkJTZXEvSDNtbTE4X0RveF8wNDMybGFuZTIvRmluYWxfUnNlcnZlcl8xOTEyMDMvQlJCMDQzMmxhbmUybm91bWlfSDNtbTE4X0RveF9fbm9ybUNvdW50X19maW5hbDE5MTIwNS5jc3YiCgojRmluYWxfTGFzdF9Sc2VydmVyXzIwMDgxMQoKYGBgCgoKQlJC44Gu44OH44O844K/IChERUcsbG9nMkZD44KS5oqc44GN5Ye644GZKQoKYGBge3IgREVHIGNsdXN0ZXIgcHJlcGFyZX0KIy0tLSBERUfjga7jg6rjgrnjg4jjga7lkbzjgbPlh7rjgZcgLS0tLS0tLS0jCmNsdXN0ZXJfQlJCbGlzdCA8LSByZWFkcjo6cmVhZF9jc3YoZmlsZXBhdGhfQlJCY2x1c3RlcikgJT4lIG11dGF0ZShjbHVzdGVyPWZhY3RvcihjbHVzdGVyLGMoMTpjbHVzdGVyX251bSkpKSAjQlJC562J44GuREVH44Gu44Oq44K544OICgojLS0tIGxvZzIgRkPjga7jg6rjgrnjg4jjga7lkbzjgbPlh7rjgZcgLS0tLS0tLS0jCnJlX0JSQl9hbGwgPC0gcmVhZHI6OnJlYWRfY3N2KGZpbGVwYXRoX0JSQl9GQ19kZXNlcSkKCiMtLS0gQlJC44Gu5YWoZ2VuZeODquOCueODiOOBruWRvOOBs+WHuuOBlyAtLS0tLS0tLSPjgIAKYWxsX0JSQmxpc3QgPC0gcmVhZHI6OnJlYWRfY3N2KGZpbGVwYXRoX0JSQmFsbGdlbmUpICNub3JtY291bnQKbnJvdyhhbGxfQlJCbGlzdCkKCiMtLS0tIwp6c2NvcmVfQlJCIDwtIHJlYWRyOjpyZWFkX2NzdihmaWxlcGF0aF9CUkJ6c2NvcmUpCm5yb3coenNjb3JlX0JSQikKIy0tLS0jCmRlZl9CUkIgPC0gcmVhZHI6OnJlYWRfdHN2KGZpbGVwYXRoX0JSQmRlZikgJT4lIG11dGF0ZShzZXE9ZmFjdG9yKHNlcSwgYygiQlJCIikpKSAgJT4lIAptdXRhdGUodGltZTEgPSB0aW1lLCByZXAxPXJlcCkgJT4lIHVuaXRlKHRpbWUxLHJlcDEsY29sPSJ0aW1lX3JlcGxpY2F0ZSIpICAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwgIjBoIiwiMjRoIiwiNDhoIikpKSAlPiUgbXV0YXRlKHR5cGU9ZmFjdG9yKHR5cGUsYygiRG94UGx1cyIsIkRveE1pbnVzIikpKSAlPiUgbXV0YXRlKHJlcD1mYWN0b3IocmVwLCBjKCIxIiwgIjIiLCAiMyIsICI0IikpKSU+JSBtdXRhdGUodGltZV9yZXBsaWNhdGU9ZmFjdG9yKHRpbWVfcmVwbGljYXRlLGMoIlVJXzEiLCAiVUlfMiIsICJVSV8zIiwgIlVJXzQiLCAiMGhfMSIsIjBoXzIiLCIyNGhfMSIsIjI0aF8yIiwiNDhoXzEiLCI0OGhfMiIsIjQ4aF8zIiwiNDhoXzQiKSkpCgojLS0tLSMKI0ZDX3JhbmtfYWxsX0JSQmxpc3QgPC0gcmVfQlJCX2FsbCAlPiUgYXJyYW5nZShkZXNjKGFicyhsb2cyRm9sZENoYW5nZSkpKSAlPiUgbXV0YXRlKFJhbms9cm93X251bWJlcigpKSAjbm9ybWNvdW50CiNucm93KEZDX3JhbmtfYWxsX0JSQmxpc3QpCiNwcmludChGQ19yYW5rX2FsbF9CUkJsaXN0KQoKIyU+JSBtdXRhdGUoY2x1c3Rlcj1mYWN0b3IoY2x1c3RlcixjKDE6Y2x1c3Rlcl9udW0pKSkgI0JSQuetieOBrkRFR+OBruODquOCueODiAoKCiMjIy0tLSBERVNlcTLjgavjgojjgoroqIjnrpfjgZfjgZ9ub3JtYWxpemVkIGNvdW5044Gu44GG44Gh44CBQlJC562J44GuREVH44Gu44Oq44K544OI44Gr44GC44Gj44Gf44KC44Gu44KS5pu444GN5Ye644GXIC0tLSMjIwojbm9ybV90YWJsZV9zZWxlY3QgPC0gbm9ybWFsaXplZGNvdW50ICU+JSBmaWx0ZXIoZW5zX2dlbmUgJWluJSBjbHVzdGVyX0JSQmxpc3QkZW5zX2dlbmUpICU+JSBmdWxsX2pvaW4oY2x1c3Rlcl9CUkJsaXN0LCAuLCBieT0iZW5zX2dlbmUiKSAjREVH44Oq44K544OI44Gubm9ybWFsaXplZCBjb3VudAojcmVhZHI6OndyaXRlX2Nzdihub3JtX3RhYmxlX3NlbGVjdCwgcGFzdGUoIi4iLGZvbGRlcl9uYW1lLCBwYXN0ZShSTkFzZXFfY2x1c3RlciwiX19ub3JtYWxpemVkY291bnRfXyIsZm9sZGVyX25hbWUsIi5jc3YiLHNlcD0iIiksc2VwPSIvIikpICNub3JtYWxpemVkIGNvdW50IGNzduOBq2dlbmXlkI3jgpLku5jjgZHjgZ/jgIIKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMgCiMtLS0tIwpub3JtX0JSQl9kZWZfb3JpZ2luYWwgPC0gcmVhZHI6OnJlYWRfY3N2KGZpbGVwYXRoX0JSQl9ub3JtY291bnQpCiNub3JtX0JSQiA8LSBub3JtX0JSQl9kZWZfb3JpZ2luYWwgJT4lIGRwbHlyOjpyZW5hbWUoVHlwZT10eXBlLHJlcD1yZXBsaWNhdGUsbm9ybT1ub3JtYWxpemVkKSAlPiUgbXV0YXRlKHR5cGU9Y2FzZV93aGVuKFR5cGU9PSJEb3htaW51cyJ+IkRveE1pbnVzIixUeXBlPT0iRG94cGx1cyJ+IkRveFBsdXMiKSkgICU+JSBtdXRhdGUoc2VxPSJCUkIiKSAlPiUgCiNtdXRhdGUodGltZTEgPSB0aW1lLCByZXAxPXJlcCkgJT4lIHVuaXRlKHRpbWUxLHJlcDEsY29sPSJ0aW1lX3JlcGxpY2F0ZSIpICAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwgIjBoIiwiMjRoIiwiNDhoIikpKSAlPiUgbXV0YXRlKHR5cGU9ZmFjdG9yKHR5cGUsYygiRG94UGx1cyIsIkRveE1pbnVzIikpKSAlPiUgbXV0YXRlKHJlcD1mYWN0b3IocmVwLCBjKCIxIiwgIjIiLCAiMyIsICI0IikpKSU+JSBtdXRhdGUodGltZV9yZXBsaWNhdGU9ZmFjdG9yKHRpbWVfcmVwbGljYXRlLGMoIlVJXzEiLCAiVUlfMiIsICJVSV8zIiwgIlVJXzQiLCAiMGhfMSIsIjBoXzIiLCIyNGhfMSIsIjI0aF8yIiwiNDhoXzEiLCI0OGhfMiIsIjQ4aF8zIiwiNDhoXzQiKSkpCgpub3JtX0JSQiA8LSBub3JtX0JSQl9kZWZfb3JpZ2luYWwgJT4lIGRwbHlyOjpyZW5hbWUobm9ybT1ub3JtYWxpemVkKSAlPiUgbXV0YXRlKHNlcT0iQlJCIikgJT4lIAptdXRhdGUodGltZTEgPSB0aW1lLCByZXAxPXJlcCkgJT4lIHVuaXRlKHRpbWUxLHJlcDEsY29sPSJ0aW1lX3JlcGxpY2F0ZSIpICAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwgIjBoIiwiMjRoIiwiNDhoIikpKSAlPiUgbXV0YXRlKHR5cGU9ZmFjdG9yKHR5cGUsYygiRG94UGx1cyIsIkRveE1pbnVzIikpKSAlPiUgbXV0YXRlKHJlcD1mYWN0b3IocmVwLCBjKCIxIiwgIjIiLCAiMyIsICI0IikpKSU+JSBtdXRhdGUodGltZV9yZXBsaWNhdGU9ZmFjdG9yKHRpbWVfcmVwbGljYXRlLGMoIlVJXzEiLCAiVUlfMiIsICJVSV8zIiwgIlVJXzQiLCAiMGhfMSIsIjBoXzIiLCIyNGhfMSIsIjI0aF8yIiwiNDhoXzEiLCI0OGhfMiIsIjQ4aF8zIiwiNDhoXzQiKSkpCgoKIyAlPiUgbXV0YXRlKGdyb3VwPWNhc2Vfd2hlbihHcm91cD09IkRveG1pbnVzX0RpZmYwaCJ+IkJSQl8waF9Eb3hNaW51cyIsR3JvdXA9PSJEb3hwbHVzX0RpZmYwaCJ+IkJSQl8waF9Eb3hQbHVzIikpCgpwcmludChub3JtX0JSQikKIy0tLS0jCgojQlJCXzJndW4gPC0gcmVhZHI6OnJlYWRfY3N2KGZpbGVwYXRoX0JSQl8yZ3VuKQoKIyIvaG9tZS9ndWVzdEEvbzcwNTc4YS9ha3V3YWthZG8va3V3YWthZG8vQlJCU2VxL0gzbW0xOF9Eb3hfMDQzMmxhbmUyL0ZpbmFsX1JzZXJ2ZXJfMTkxMjAzL0xSVC9jbHVzdGVyaW5nX1hzTFJUYWxsX19CUkIwNDMybGFuZTJub3VtaV9IM21tMThfRG94LmNzdiIKIy0tLSBERUfjga7jg6rjgrnjg4jjgavkvY3nva7mg4XloLHjgpLliqDjgYjjgosKI2JlZGZpbGVfY2x1c3RlciA8LSBiZWRmaWxlICU+JSBmaWx0ZXIoZW5zX2dlbmUgJWluJSBjbHVzdGVyX0JSQmxpc3QkZW5zX2dlbmUpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLFRTU19yZWdpb24sZ2VuZV9yZWdpb24sU3RyYW5kKSAlPiUgZnVsbF9qb2luKGNsdXN0ZXJfQlJCbGlzdCwgLiwgYnk9ImVuc19nZW5lIikgI+S9jee9ruaDheWgseOBguOCigojIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsVFNTX3JlZ2lvbixnZW5lX3JlZ2lvbixTdHJhbmQpCgojTm9ybUNvdW50QlJCbWF0IDwtIHJlYWRyOjpyZWFkX2NzdigiL2hvbWUvZ3Vlc3RBL283MDU3OGEvYWt1d2FrYWRvL2t1d2FrYWRvL0JSQlNlcS9IM21tMThfRG94XzA0MzJsYW5lMi9GaW5hbF9Sc2VydmVyXzE5MTIwMy9IM21tMThLT18zVDNfRG94X25vcm1Db3VudF9nZW5lbmFtZS5jc3YiKQoKYGBgCgoKCgojIyBjb21wYXJlIEgzLjMgY2x1c3RlciAmIEJSQiBERUcgY2x1c3RlcgoKCmBgYHtyIGNvbXBhcmUgY2x1c3RlciAmIEJSQn0KbGlzdDEgPC0gcnJyZXNfYWxsSDNwMyAlPiUgZmlsdGVyKGVuc19nZW5lICVpbiUgY2x1c3Rlcl9CUkJsaXN0JGVuc19nZW5lKSAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHN1bW1hcmlzZShCUkJjb3VudD1uKCksZ2VuZWxpc3Q9cGFzdGUoZXh0X2dlbmUsY29sbGFwc2U9IiwgIiksSURsaXN0PXBhc3RlKGVuc19nZW5lLGNvbGxhcHNlPSIsICIpKQoKI2xpc3QyIDwtIHJycmVzX0gzcDNjbHVzMiAlPiUgZmlsdGVyKGVuc19nZW5lICVpbiUgY2x1c3Rlcl9CUkJsaXN0JGVuc19nZW5lKSAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHN1bW1hcmlzZShCUkJjb3VudD1uKCksZ2VuZWxpc3Q9cGFzdGUoZXh0X2dlbmUsY29sbGFwc2U9IiwgIiksSURsaXN0PXBhc3RlKGVuc19nZW5lLGNvbGxhcHNlPSIsICIpKQoKcmVhZHI6OndyaXRlX2NzdihsaXN0MSwiQ29tcGFyZV9DaElMQVRBQ19jbHVzdGVyX3ZzX0JSQkRFR3MuY3N2IikKI3JlYWRyOjp3cml0ZV9jc3YobGlzdDIsIkNvbXBhcmVfQ2hJTEFUQUNfY2x1c3RlcjJfdnNfQlJCREVHcy5jc3YiKQoKcHJpbnQobGlzdDEpCgpjbHVzdGVyMSA8LSBjbHVzdGVyX0JSQmxpc3QgJT4lIGZpbHRlcihjbHVzdGVyPT0iMSIpCmNsdXN0ZXIyIDwtIGNsdXN0ZXJfQlJCbGlzdCAlPiUgZmlsdGVyKGNsdXN0ZXI9PSIyIikKY2x1c3RlcjMgPC0gY2x1c3Rlcl9CUkJsaXN0ICU+JSBmaWx0ZXIoY2x1c3Rlcj09IjMiKQpjbHVzdGVyNCA8LSBjbHVzdGVyX0JSQmxpc3QgJT4lIGZpbHRlcihjbHVzdGVyPT0iNCIpCgoKbGlzdGNsdXMgPC0gcnJyZXNfYWxsSDNwMyAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSxleHRfZ2VuZSxjbHVzdGVyKSAlPiUgZmlsdGVyKGVuc19nZW5lICVpbiUgY2x1c3Rlcl9CUkJsaXN0JGVuc19nZW5lKSAlPiUgbGVmdF9qb2luKGRwbHlyOjpzZWxlY3QoY2x1c3Rlcl9CUkJsaXN0LGVuc19nZW5lLGNsdXN0ZXIpICU+JSBkcGx5cjo6cmVuYW1lKEJSQmNsdXM9Y2x1c3RlcikpICU+JSBncm91cF9ieShjbHVzdGVyLEJSQmNsdXMpICU+JSBzdW1tYXJpc2UoY291bnQ9bigpLGdlbmVsaXN0PXBhc3RlKGV4dF9nZW5lLGNvbGxhcHNlPSIsICIpLElEbGlzdD1wYXN0ZShlbnNfZ2VuZSxjb2xsYXBzZT0iLCAiKSkKCmxpc3RjbHVzMiA8LSBsaXN0Y2x1cyAlPiUgZHBseXI6OnNlbGVjdChjbHVzdGVyLEJSQmNsdXMsY291bnQpICU+JSBtdXRhdGUoQlJCY2x1cz1wYXN0ZSgiQlJCY2x1c3RlciIsQlJCY2x1cyxzZXA9IiIpKSAlPiUgc3ByZWFkKGtleT1CUkJjbHVzLHZhbHVlPWNvdW50LCBmaWxsID0gMCkKCgpyZWFkcjo6d3JpdGVfY3N2KGxpc3RjbHVzLCIuL0NvbXBhcmUvQ29tcGFyZV9DaElMQVRBQ19jbHVzdGVyX3ZzX0JSQkRFR3Nfc3VtbWFyeS5jc3YiKQpyZWFkcjo6d3JpdGVfY3N2KGxpc3RjbHVzMiwiLi9Db21wYXJlL0NvbXBhcmVfQ2hJTEFUQUNfY2x1c3Rlcl92c19CUkJERUdzX3N1bW1hcnljb3VudC5jc3YiKQoKcHJpbnQobGlzdGNsdXMpCnByaW50KGxpc3RjbHVzMikKCgpgYGAKCmBgYHtyIG1vc2FpYyB0aWxlIHNldHVwIEgzcDNCUkJsaXN0Y2x1cywgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDN9CgojLS0tIwoKSDNwM0JSQmxpc3RjbHVzIDwtIGxpc3RjbHVzMiAlPiUgIG11dGF0ZShIM3AzY2x1c3Rlcj1wYXN0ZShjbHVzdGVyLHNlcCA9ICIiKSkKI0gzcDNCUkJsaXN0Y2x1cyA8LSBsaXN0Y2x1czIgJT4lICBtdXRhdGUoSDNwM2NsdXN0ZXI9cGFzdGUoIkgzcDNjbHVzdGVyIixjbHVzdGVyLHNlcCA9ICIiKSkKCkgzcDNCUkJsaXN0Y2x1c19tYXQgPC0gSDNwM0JSQmxpc3RjbHVzICU+JSB1bmdyb3VwKCkgJT4lIGRwbHlyOjpzZWxlY3QoLWNsdXN0ZXIsLUgzcDNjbHVzdGVyKSAlPiUgYXMubWF0cml4KCkKcm93bmFtZXMoSDNwM0JSQmxpc3RjbHVzX21hdCkgPC0gSDNwM0JSQmxpc3RjbHVzJEgzcDNjbHVzdGVyCgpIM3AzQlJCbGlzdGNsdXNfY291bnQgPC0gSDNwM0JSQmxpc3RjbHVzICU+JSB1bmdyb3VwKCkgJT4lIGRwbHlyOjpzZWxlY3QoLWNsdXN0ZXIpICU+JSBnYXRoZXIoa2V5PXNhbXBsZSx2YWx1ZT1jb3VudCwtSDNwM2NsdXN0ZXIpCgojLS0tIwoKcmVzdWx0Y2hpc3EgPC0gY2hpc3EudGVzdChIM3AzQlJCbGlzdGNsdXNfbWF0KQpyZXN1bHRjaGlzcQoKI3Jlc3VsdGNoaXNxJHJlc2lkdWFscwojcmVzdWx0Y2hpc3EkZXhwZWN0ZWQKcmVzdWx0Y2hpc3EkZXhwZWN0ZWQgJT4lIHN1bSgpCgojcmVzaWR1YWxzIDwtIHJlc3VsdGNoaXNxJHJlc2lkdWFscyAlPiUgYXMuZGF0YS5mcmFtZSguKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIkgzcDNjbHVzdGVyIikgJT4lIGdhdGhlcihrZXk9c2FtcGxlLHZhbHVlPXZhbHVlLC0oSDNwM2NsdXN0ZXIpKSAlPiUgbXV0YXRlKEgzcDNjbHVzdGVyPWZhY3RvcihIM3AzY2x1c3RlcixjKCJIM3AzY2x1c3RlcjYiLCJIM3AzY2x1c3RlcjUiLCJIM3AzY2x1c3RlcjQiLCJIM3AzY2x1c3RlcjMiLCJIM3AzY2x1c3RlcjIiLCJIM3AzY2x1c3RlcjEiKSkpCgojSDNwM0JSQmxpc3RjbHVzX2NvdW50X3Jlc2lkdWFscyA8LSByZXNpZHVhbHMgJT4lIGxlZnRfam9pbihIM3AzQlJCbGlzdGNsdXNfY291bnQpICAlPiUgbXV0YXRlKEgzcDNjbHVzdGVyPWZhY3RvcihIM3AzY2x1c3RlcixjKCJIM3AzY2x1c3RlcjYiLCJIM3AzY2x1c3RlcjUiLCJIM3AzY2x1c3RlcjQiLCJIM3AzY2x1c3RlcjMiLCJIM3AzY2x1c3RlcjIiLCJIM3AzY2x1c3RlcjEiKSkpCgpyZXNpZHVhbHMgPC0gcmVzdWx0Y2hpc3EkcmVzaWR1YWxzICU+JSBhcy5kYXRhLmZyYW1lKC4pICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiSDNwM2NsdXN0ZXIiKSAlPiUgZ2F0aGVyKGtleT1zYW1wbGUsdmFsdWU9dmFsdWUsLShIM3AzY2x1c3RlcikpICU+JSBtdXRhdGUoSDNwM2NsdXN0ZXI9ZmFjdG9yKEgzcDNjbHVzdGVyLGMoIjEiLCIyIiwiMyIsIjQiLCI1IiwiNiIpKSkgICU+JSBtdXRhdGUoQlJCY2x1c3Rlcj1nc3ViKCJCUkJjbHVzdGVyIiwiIixzYW1wbGUpKSAlPiUgbXV0YXRlKEJSQmNsdXN0ZXI9ZmFjdG9yKEJSQmNsdXN0ZXIsYygiNCIsIjMiLCIyIiwiMSIpKSkgCgpIM3AzQlJCbGlzdGNsdXNfY291bnRfcmVzaWR1YWxzIDwtIHJlc2lkdWFscyAlPiUgbGVmdF9qb2luKEgzcDNCUkJsaXN0Y2x1c19jb3VudCkKCiMlPiUgbXV0YXRlKEgzcDNjbHVzdGVyPWZhY3RvcihIM3AzY2x1c3RlcixjKCIxIiwiMiIsIjMiLCI0IiwiNSIsIjYiKSkpCgpwYXN0ZShyZXN1bHRjaGlzcSRtZXRob2QsIlJlc2lkdWFsIixzZXA9IjogIikKCmNoaXNxX3Bsb3QgPC0gSDNwM0JSQmxpc3RjbHVzX2NvdW50X3Jlc2lkdWFscyAlPiUgZ2dwbG90KGFlcyh4PUgzcDNjbHVzdGVyLCB5PUJSQmNsdXN0ZXIsIGZpbGw9dmFsdWUsIGxhYmVsPWNvdW50KSkgKyBnZW9tX3RpbGUoKSArIGdlb21fdGV4dChhZXMoeD1IM3AzY2x1c3RlciwgeT1CUkJjbHVzdGVyLCBsYWJlbD1hcy5jaGFyYWN0ZXIoY291bnQpKSkgKyAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSJibHVlIiwgaGlnaD0icmVkIiwgbmEudmFsdWU9ImJsYWNrIiwgbmFtZT0iIikgKyB0aGVtZShheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yKSxsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKyB0aGVtZV9taW5pbWFsKCkgKyB5bGFiKCJCUkIgREVHIGNsdXN0ZXIiKSArIHhsYWIoIkgzLjMgY2x1c3RlciIpCgpjaGlzcV9wbG90Cmdnc2F2ZShmaWxlPSIuL0NvbXBhcmUvSDNwM0JSQmxpc3RjbHVzLnBkZiIsIHBsb3QgPSBjaGlzcV9wbG90LCBkcGkgPSAxMDAsIHdpZHRoID0gNSwgaGVpZ2h0ID0gMyxsaW1pdHNpemUgPSBGQUxTRSkKCgpjaGlzcV9wbG90MiA8LSBIM3AzQlJCbGlzdGNsdXNfY291bnRfcmVzaWR1YWxzICU+JSBnZ3Bsb3QoYWVzKHg9SDNwM2NsdXN0ZXIsIHk9QlJCY2x1c3RlciwgZmlsbD12YWx1ZSwgbGFiZWw9Y291bnQpKSArIGdlb21fdGlsZSgpICsgIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iYmx1ZSIsIGhpZ2g9InJlZCIsIG5hLnZhbHVlPSJibGFjayIsIG5hbWU9IiIpICsgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MiksbGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgdGhlbWVfbWluaW1hbCgpICArIHlsYWIoIkJSQiBERUcgY2x1c3RlciIpICsgeGxhYigiSDMuMyBjbHVzdGVyIikKCmNoaXNxX3Bsb3QyCmdnc2F2ZShmaWxlPSIuL0NvbXBhcmUvSDNwM0JSQmxpc3RjbHVzX25vdGl0bGUucGRmIiwgcGxvdCA9IGNoaXNxX3Bsb3QyLCBkcGkgPSAxMDAsIHdpZHRoID0gNSwgaGVpZ2h0ID0gMyxsaW1pdHNpemUgPSBGQUxTRSkKCgpIM3AzQlJCbGlzdGNsdXNfY291bnRfcmVzaWR1YWxzICU+JSByZWFkcjo6d3JpdGVfY3N2KCIuL0NvbXBhcmUvSDNwM0JSQmxpc3RjbHVzLmNzdiIpCgpgYGAKCgoKIyMtLS0tLS0tLS0g44Oq44K544OI44KS5L+d5a2YIC0tLS0tLS0tLS0tLS0jCiMtLSDnorroqo0gLS0jCgpycnJlc19hbGxIM3AzICU+JSBmaWx0ZXIoZW5zX2dlbmUgJWluJSBjbHVzdGVyX0JSQmxpc3QkZW5zX2dlbmUpICU+JSBsZWZ0X2pvaW4oY2x1c3Rlcl9CUkJsaXN0ICU+JSBkcGx5cjo6cmVuYW1lKEJSQmNsdXM9Y2x1c3RlcikpICU+JSBkcGx5cjo6c2VsZWN0KGNsdXN0ZXIpJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSBzdW1tYXJpc2UoY291bnQ9bigpKQoKcnJyZXNfYWxsSDNwMyAlPiUgZmlsdGVyKGVuc19nZW5lICVpbiUgY2x1c3Rlcl9CUkJsaXN0JGVuc19nZW5lKSAlPiUgbGVmdF9qb2luKGNsdXN0ZXJfQlJCbGlzdCAlPiUgZHBseXI6OnJlbmFtZShCUkJjbHVzPWNsdXN0ZXIpKSAlPiUgZHBseXI6OnNlbGVjdChCUkJjbHVzLGNsdXN0ZXIpICU+JSBncm91cF9ieShCUkJjbHVzLGNsdXN0ZXIpICU+JSBzdW1tYXJpc2UoY291bnQ9bigpKQoKCiMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwoKCi0tLS0tLS0tCgojIGxvZzJGQ+OCkuOBvuOBqOOCgeOBpuioiOeul+OBmeOCiwoKIyMjIyBIM3AzIGNsdXN0ZXIzIOOBrkNoSUwgbm9ybWFsaXplZCBjb3VudAoKbm9ybWFsaXplZCBjb3VudCAoQlJCIERFRykg44Gu44CAZGVmdGFibGXnrYkK77yI55m654++44GM5L2O44GE44KC44Gu44GvQ3V077yJCgrjgb7jgZrjgIFCUkLjgafpgbrkvJ3lrZDnmbrnj77jgYzljYHliIblpKfjgY3jgYTjgoLjga7jgavntZ7jgorovrzjgoDvvIhDdXQgb2ZmIOODquOCueODiOOBruS9nOaIkO+8iQoKYGBge3Igbm9ybSBjb3VudCBkZWYgdGFibGUgMjAwODExdmVyfQoKU2V0X2N1dG9mZiA8LSAxMC4wCgojIyDlkITmmYLliLvjga7lubPlnYfjgpLoqIjnrpfjgZfjgIFub3JtYWxpemVkIGNvdW50ID4gMTAg44KS6LaF44GI44KL44KC44Gu44KS5oq95Ye644GZ44KL44CCCgojLS0tLS0gU0tN44GoQ1RY44Gu44G/5Y+W44KK5Ye644GZIC0tLSMgMjAxOTEyMDUKI25vcm1fQlJCX2FsbCA8LSBub3JtX0JSQiAlPiUgZ2F0aGVyKCJzYW1wbGUiLCAibm9ybWFsaXplZCIsLShlbnNfZ2VuZSkpICU+JSBpbm5lcl9qb2luKGRlZiwgYnkgPSAic2FtcGxlIikKI25vcm1fQlJCX2FsbCA8LSBub3JtX0JSQl9hbGwgJT4lIGZpbHRlcihpbnRhY3RfQ1RYPT0iQ1RYInxpbnRhY3RfQ1RYPT0iU0tNIikgJT4lIG11dGF0ZShXVF9LTz1mYWN0b3IoV1RfS08sIGMoIkgzbW0xOEtPIiwiV1QiKSkpICU+JSBtdXRhdGUoRGF5PWZhY3RvcihEYXksIGMoIkRheTAiLCJEYXk1IiwiRGF5MTQiKSkpICU+JSBtdXRhdGUoaW50YWN0X0NUWD1mYWN0b3IoaW50YWN0X0NUWCwgYygiQ1RYIiwiU0tNIikpKQoKI25vdG1fcGxvdGxpc3RfY3V0b2ZmIDwtIG5vcm1fcGxvdGxpc3RfYWxsICU+JSBhbm5vdGF0ZSgpICU+JSBncm91cF9ieShlbnNfZ2VuZSwgZXh0X2dlbmUsIERheSwgaW50YWN0X0NUWCkgJT4lIHN1bW1hcml6ZShncm91cE1lYW49bWVhbihub3JtYWxpemVkKSkgICU+JSB1bmdyb3VwKCkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsIGV4dF9nZW5lKSAlPiUgdW5pcXVlKCkKCgpub3JtX0JSQl9iZWZvcmVjdXRvZmYgPC0gbm9ybV9CUkIgJT4lIGdyb3VwX2J5KGVuc19nZW5lLCBleHRfZ2VuZSwgc2VxLCB0aW1lKSAlPiUgc3VtbWFyaXplKGdyb3VwTWVhbj1tZWFuKG5vcm0pKQpucm93KG5vcm1fQlJCX2JlZm9yZWN1dG9mZikKbnJvdyhub3JtX0JSQl9iZWZvcmVjdXRvZmYgJT4lIHVuZ3JvdXAoKSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSwgZXh0X2dlbmUpICU+JSB1bmlxdWUoKSkgI+OBk+OBruWApOOCkk1BcGxvdOOBrnjou7jjgavkvb/nlKgKCnByaW50KCItLS0gY3V0IG9mZiAtLS0iKQpub3JtX0JSQl9jdXRvZmYgPC0gbm9ybV9CUkJfYmVmb3JlY3V0b2ZmICU+JSBmaWx0ZXIoZ3JvdXBNZWFuID4gU2V0X2N1dG9mZikgJT4lIHVuZ3JvdXAoKQpucm93KG5vcm1fQlJCX2N1dG9mZikKCm5vcm1fQlJCX2N1dG9mZl9saXN0IDwtbm9ybV9CUkJfY3V0b2ZmICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLCBleHRfZ2VuZSkgJT4lIHVuaXF1ZSgpCm5yb3cobm9ybV9CUkJfY3V0b2ZmX2xpc3QpCgpub3JtX0JSQl9iZWZvcmVjdXRvZmYgJT4lIHJlYWRyOjp3cml0ZV9jc3YoIi4vbG9nMkZDL3RhYmxlcy9Ob3JtX0JSQl9ncm91cE1lYW4uY3N2IikKbm9ybV9CUkJfY3V0b2ZmICAlPiUgcmVhZHI6OndyaXRlX2NzdigibG9nMkZDL3RhYmxlcy9Ob3JtX0JSQl9ncm91cE1lYW5fY3V0b2ZmMTAuY3N2IikKbm9ybV9CUkJfY3V0b2ZmX2xpc3QgICU+JSByZWFkcjo6d3JpdGVfY3N2KCJsb2cyRkMvdGFibGVzL05vcm1fQlJCX2dyb3VwTWVhbl9jdXRvZmYxMF9nZW5lbGlzdC5jc3YiKQoKYGBgCgpgYGB7ciBleHRyYWN0UmVzM30KCnJlX0gzcDNfRkNfY3V0b2ZmIDwtIHJlX0gzcDNfYWxsICU+JSBtdXRhdGUoc2VxPSJIM3AzIiwgdGltZT1nc3ViKCJncm91cF9IM3AzXyIsIiIsYXNwZWN0KSkgJT4lIG11dGF0ZSh0aW1lPWdzdWIoIl9Eb3hwbHVzX3ZzX21pbnVzIiwiIix0aW1lKSkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsZXh0X2dlbmUsYmlvdHlwZSxjaHIsICBsb2cyRm9sZENoYW5nZSxzZXEsdGltZSkgJT4lIGZpbHRlcihlbnNfZ2VuZSAlaW4lIG5vcm1fQlJCX2N1dG9mZiRlbnNfZ2VuZSkKCnJlX0gzSzRtZTNfRkNfY3V0b2ZmIDwtIHJlX0gzSzRtZTNfYWxsICU+JSBtdXRhdGUoc2VxPSJIM0s0bWUzIiwgdGltZT1nc3ViKCJncm91cF9IM0s0bWUzXyIsIiIsYXNwZWN0KSkgJT4lIG11dGF0ZSh0aW1lPWdzdWIoIl9Eb3hwbHVzX3ZzX21pbnVzIiwiIix0aW1lKSkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsZXh0X2dlbmUsYmlvdHlwZSxjaHIsICBsb2cyRm9sZENoYW5nZSxzZXEsdGltZSkgICU+JSBmaWx0ZXIoZW5zX2dlbmUgJWluJSBub3JtX0JSQl9jdXRvZmYkZW5zX2dlbmUpCgpyZV9IM0syN2FjX0ZDX2N1dG9mZiA8LSByZV9IM0syN2FjX2FsbCAlPiUgbXV0YXRlKHNlcT0iSDNLMjdhYyIsIHRpbWU9Z3N1YigiZ3JvdXBfSDNLMjdhY18iLCIiLGFzcGVjdCkpICU+JSBtdXRhdGUodGltZT1nc3ViKCJfRG94cGx1c192c19taW51cyIsIiIsdGltZSkpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLGV4dF9nZW5lLGJpb3R5cGUsY2hyLCAgbG9nMkZvbGRDaGFuZ2Usc2VxLHRpbWUpICAlPiUgZmlsdGVyKGVuc19nZW5lICVpbiUgbm9ybV9CUkJfY3V0b2ZmJGVuc19nZW5lKQoKcmVfSDNLMjdtZTNfRkNfY3V0b2ZmIDwtIHJlX0gzSzI3bWUzX2FsbCAlPiUgbXV0YXRlKHNlcT0iSDNLMjdtZTMiLCB0aW1lPWdzdWIoImdyb3VwX0gzSzI3bWUzXyIsIiIsYXNwZWN0KSkgJT4lIG11dGF0ZSh0aW1lPWdzdWIoIl9Eb3hwbHVzX3ZzX21pbnVzIiwiIix0aW1lKSkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsZXh0X2dlbmUsYmlvdHlwZSxjaHIsICBsb2cyRm9sZENoYW5nZSxzZXEsdGltZSkgICU+JSBmaWx0ZXIoZW5zX2dlbmUgJWluJSBub3JtX0JSQl9jdXRvZmYkZW5zX2dlbmUpCgpyZV9BVEFDX0ZDX2N1dG9mZiA8LSByZV9BVEFDX2FsbCAlPiUgbXV0YXRlKHNlcT0iQVRBQyIsIHRpbWU9Z3N1YigiZ3JvdXBfQVRBQ18iLCIiLGFzcGVjdCkpICU+JSBtdXRhdGUodGltZT1nc3ViKCJfRG94cGx1c192c19taW51cyIsIiIsdGltZSkpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLGV4dF9nZW5lLGJpb3R5cGUsY2hyLCAgbG9nMkZvbGRDaGFuZ2Usc2VxLHRpbWUpICAlPiUgZmlsdGVyKGVuc19nZW5lICVpbiUgbm9ybV9CUkJfY3V0b2ZmJGVuc19nZW5lKQoKcmVfQlJCX0ZDX2N1dG9mZiA8LSByZV9CUkJfYWxsICU+JSBtdXRhdGUoc2VxPSJCUkIiLCB0aW1lPWdzdWIoImdyb3VwXyIsIiIsYXNwZWN0KSkgJT4lIG11dGF0ZSh0aW1lPWdzdWIoIl9Eb3hwbHVzX3ZzX21pbnVzIiwiIix0aW1lKSkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsZXh0X2dlbmUsYmlvdHlwZSxjaHIsICBsb2cyRm9sZENoYW5nZSxzZXEsdGltZSkgICU+JSBmaWx0ZXIoZW5zX2dlbmUgJWluJSBub3JtX0JSQl9jdXRvZmYkZW5zX2dlbmUpCgoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9sb2cyRkNfSDNwM19jdXRvZmYxMC5jc3YiCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KHJlX0gzcDNfRkNfY3V0b2ZmLGZpbGVuYW1lKQpucm93KHJlX0gzcDNfRkNfY3V0b2ZmKQoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9sb2cyRkNfSDNLNG1lM19jdXRvZmYxMC5jc3YiCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KHJlX0gzSzRtZTNfRkNfY3V0b2ZmLGZpbGVuYW1lKQpucm93KHJlX0gzSzRtZTNfRkNfY3V0b2ZmKQoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9sb2cyRkNfSDNLMjdhY19jdXRvZmYxMC5jc3YiCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KHJlX0gzSzI3YWNfRkNfY3V0b2ZmLGZpbGVuYW1lKQpucm93KHJlX0gzSzI3YWNfRkNfY3V0b2ZmKQoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9sb2cyRkNfSDNLMjdtZTNfY3V0b2ZmMTAuY3N2IgpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2NzdihyZV9IM0syN21lM19GQ19jdXRvZmYsZmlsZW5hbWUpCm5yb3cocmVfSDNLMjdtZTNfRkNfY3V0b2ZmKQoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9sbzJnRkNfQVRBQ19jdXRvZmYxMC5jc3YiCnByaW50KGZpbGVuYW1lKQpyZWFkcjo6d3JpdGVfY3N2KHJlX0FUQUNfRkNfY3V0b2ZmLGZpbGVuYW1lKQpucm93KHJlX0FUQUNfRkNfY3V0b2ZmKQoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9sb2cyRkNfQlJCX2N1dG9mZjEwLmNzdiIKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3YocmVfQlJCX0ZDX2N1dG9mZixmaWxlbmFtZSkKbnJvdyhyZV9CUkJfRkNfY3V0b2ZmKQoKCiMjIOWFqOOBpue1kOWQiApyZV9hbGxfRkNfY3V0b2ZmIDwtIGJpbmRfcm93cyhyZV9IM3AzX0ZDX2N1dG9mZiwgcmVfSDNLNG1lM19GQ19jdXRvZmYpICU+JSBiaW5kX3Jvd3MocmVfSDNLMjdhY19GQ19jdXRvZmYpICU+JSBiaW5kX3Jvd3MocmVfSDNLMjdtZTNfRkNfY3V0b2ZmKSAlPiUgYmluZF9yb3dzKHJlX0FUQUNfRkNfY3V0b2ZmKSAlPiUgYmluZF9yb3dzKHJlX0JSQl9GQ19jdXRvZmYpICU+JSBtdXRhdGUoc2VxPWZhY3RvcihzZXEsIGMoIkgzcDMiLCAiSDNLNG1lMyIsIkgzSzI3YWMiLCJIM0syN21lMyIsIkFUQUMiLCJCUkIiKSkpICU+JSBtdXRhdGUodGltZT1mYWN0b3IodGltZSwgYygiVUkiLCAiMGgiLCIyNGgiLCI0OGgiKSkpIAoKcmVfYWxsX0ZDX2N1dG9mZgoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9sb2cyRkNfQ2hJTEFUQUNCUkJfY3V0b2ZmMTAuY3N2IgpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2NzdihyZV9hbGxfRkNfY3V0b2ZmLGZpbGVuYW1lKQpucm93KHJlX2FsbF9GQ19jdXRvZmYpCgpgYGAKCgpgYGB7ciBzcHJlYWQgRkMgZXh0cmFjdFJlczN9CgpzcHJlYWRfYWxsX0ZDX2N1dG9mZiA8LSByZV9hbGxfRkNfY3V0b2ZmICU+JSBncm91cF9ieShlbnNfZ2VuZSwgZXh0X2dlbmUsIGJpb3R5cGUsIGNociwgdGltZSkgJT4lIHNwcmVhZChrZXk9c2VxLHZhbHVlPWxvZzJGb2xkQ2hhbmdlKQpucm93KHNwcmVhZF9hbGxfRkNfY3V0b2ZmKQpzcHJlYWRfYWxsX0ZDX2N1dG9mZiA8LSBzcHJlYWRfYWxsX0ZDX2N1dG9mZiAlPiUgbGVmdF9qb2luKGRwbHlyOjpzZWxlY3Qobm9ybV9CUkJfY3V0b2ZmLCBlbnNfZ2VuZSwgZXh0X2dlbmUsIHRpbWUsIGdyb3VwTWVhbikgJT4lIGRwbHlyOjpyZW5hbWUoQlJCZ3JvdXBNZWFuPWdyb3VwTWVhbikpCm5yb3coc3ByZWFkX2FsbF9GQ19jdXRvZmYpCgpmaWxlbmFtZSA8LSAiLi9sb2cyRkMvdGFibGVzL1NwcmVhZF9sb2cyRkNfQ2hJTEFUQUNCUkJfY3V0b2ZmMTAuY3N2IgpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2NzdihzcHJlYWRfYWxsX0ZDX2N1dG9mZixmaWxlbmFtZSkKCgpgYGAKCmBgYHtyIHNwcmVhZCBGQyBleHRyYWN0UmVzMyBhZGQgQ2x1c3Rlcn0KCnNwcmVhZF9hbGxfRkNfY3V0b2ZmX2NsdXMgPC0gc3ByZWFkX2FsbF9GQ19jdXRvZmYgJT4lIGxlZnRfam9pbihkcGx5cjo6c2VsZWN0KHJycmVzX2FsbEgzcDMsZW5zX2dlbmUsY2x1c3RlcikpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzdGVyPWNsdXN0ZXIpICU+JSBsZWZ0X2pvaW4oZHBseXI6OnNlbGVjdChjbHVzdGVyX0JSQmxpc3QsZW5zX2dlbmUsY2x1c3RlcikpICU+JSBkcGx5cjo6cmVuYW1lKEJSQkRFR2NsdXN0ZXI9Y2x1c3RlcikKCmZpbGVuYW1lIDwtICIuL2xvZzJGQy90YWJsZXMvU3ByZWFkX2xvZzJGQ19DaElMQVRBQ0JSQl9jdXRvZmYxMF9fd2l0aENsdXN0ZXIuY3N2IgpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2NzdihzcHJlYWRfYWxsX0ZDX2N1dG9mZl9jbHVzLGZpbGVuYW1lKQpucm93KHNwcmVhZF9hbGxfRkNfY3V0b2ZmX2NsdXMpCgoKc3ByZWFkX2FsbF9GQ19jdXRvZmZfY2x1cyAlPiUgdW5ncm91cCgpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLEgzcDNjbHVzdGVyKSAlPiUgdW5pcXVlKCkgJT4lIGdyb3VwX2J5KEgzcDNjbHVzdGVyKSAlPiUgc3VtbWFyaXplKEgzcDNfY3V0b2ZmX2NvdW50PW4oKSkgCnJycmVzX2FsbEgzcDMgICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgc3VtbWFyaXplKEgzcDNfZ2VuZUFsbGNvdW50PW4oKSkKYGBgCgpgYGB7ciBzZWxlY3Qgc3ByZWFkIEZDIENsdXN0ZXIgSDNwMyBjbHVzM30KZl9nZW5lX0gzcDNjbHVzMyA8LSBmdW5jdGlvbih4KSB4ICU+JSBmaWx0ZXIoSDNwM2NsdXN0ZXI9PSIzIikKZl9nZW5lX0JSQmNsdXMzIDwtIGZ1bmN0aW9uKHgpIHggJT4lIGZpbHRlcihCUkJERUdjbHVzdGVyPT0iMyIpCmxpc3RfZ2VuZV9xcGNyIDwtICBjKCJBY3RhMSIsIk15aDMiLCJUdG4iLCJNeW9nIikKCnNwcmVhZF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyA8LSBzcHJlYWRfYWxsX0ZDX2N1dG9mZl9jbHVzICAlPiUgdW5ncm91cCgpICU+JSBmX2dlbmVfSDNwM2NsdXMzCm5yb3coc3ByZWFkX2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzKQoKZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9TcHJlYWRfbG9nMkZDX0NoSUxBVEFDQlJCX2N1dG9mZjEwX193aXRoQ2x1c3Rlcl9fSDNwM2NsdXMzLmNzdiIKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3Yoc3ByZWFkX2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzLGZpbGVuYW1lKQoKCnNwcmVhZF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMwpzcHJlYWRfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZfZ2VuZV9IM3AzY2x1czMgJT4lIGZfZ2VuZV9CUkJjbHVzMwpzcHJlYWRfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZfZ2VuZV9IM3AzY2x1czMgJT4lIGZfZ2VuZV9CUkJjbHVzMyAlPiUgZmlsdGVyKGV4dF9nZW5lICVpbiUgbGlzdF9nZW5lX3FwY3IpCgpIM3AzY2x1czNjdXRvZmYgPC0gc3ByZWFkX2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSB1bmdyb3VwKCkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUpICU+JSB1bmlxdWUoKSAlPiUgbnJvdygpIApIM3AzY2x1czNjdXRvZmZfYnJiY2x1czMgPC0gc3ByZWFkX2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBmX2dlbmVfQlJCY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSkgJT4lIHVuaXF1ZSgpICU+JSBucm93KCkKCm5yb3coel9IM3AzY2x1czMpCkgzcDNjbHVzM2N1dG9mZgpIM3AzY2x1czNjdXRvZmZfYnJiY2x1czMKCmBgYAoKICAKYGBge3Igc3VtbWFyeSBwbG90IEZDIENsdXN0ZXIgSDNwMyBjbHVzM30KCnBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgPC0gc3ByZWFkX2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBkcGx5cjo6bXV0YXRlKGxhYmVsX3RleHQgPSBkcGx5cjo6Y2FzZV93aGVuKGV4dF9nZW5lICVpbiUgbGlzdF9nZW5lX3FwY3IgfiBleHRfZ2VuZSwgVFJVRSB+ICIiKSxzaGFwZSA9IGRwbHlyOjpjYXNlX3doZW4oZXh0X2dlbmUgJWluJSBsaXN0X2dlbmVfcXBjciB+ICJUUlVFIiwgVFJVRSB+ICJGQUxTRSIpKQoKbnJvdyhwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzKQoKcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBmaWx0ZXIoIWlzLm5hKEJSQmdyb3VwTWVhbikpICMgZ3JvdXBNZWFuID4gMTDjga7jgb/mrovjgZkKCm5yb3cocGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMykKCgpmaWxlbmFtZSA8LSAiLi9sb2cyRkMvdGFibGVzL1Bsb3RfbG9nMkZDX0NoSUxBVEFDQlJCX2N1dG9mZjEwX193aXRoQ2x1c3Rlcl9fSDNwM2NsdXMzLmNzdiIKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3YocGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyxmaWxlbmFtZSkKCnBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGdyb3VwX2J5KHRpbWUpICU+JSBzdW1tYXJpc2UoY291bnQ9bigpKSAj5Zuz5Lit44Gu5pWwCnBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZfZ2VuZV9CUkJjbHVzMyAlPiUgZ3JvdXBfYnkodGltZSkgJT4lIHN1bW1hcmlzZShjb3VudD1uKCkpICPlm7PkuK3jga7mlbAoQlJCIERFRyBjbHVzdGVyM+OBruOBvykKCmBgYAoKCgoKCiMjIyBDYWxjdWxhdGUgQ29ycmVsYXRpb24gSDMuMyBldGMuIHZzIEJSQiAoQWxsICYgQlJCIERFRyBDbHVzdGVyMykKCuato+imj+WIhuW4g+OBquOCieODlOOCouOCveODs+OBoOOBjOOAgeS7iuWbnuato+imj+WIhuW4g+OBp+OBr+OBquOBhOOBruOBp+OCueODlOOCouODnuODs+OBrumghuS9jeebuOmWouS/guaVsArjgpLkvb/jgYYKCmBgYHtyIGNvcnJlIEgzcDMgY2x1c3RlcjMgQWxsIFVJLTQ4aCBIM3AzX0JSQiBzcGVhcm1hbn0KClRpbWVfbGlzdCA8LSBjKCJVSSIsIjBoIiwiMjRoIiwiNDhoIikKCgpDb3VudF9GQ19jdXRvZmZfSDNwM2NsdXMzIDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZ3JvdXBfYnkodGltZSkgJT4lIHN1bW1hcmlzZShQbG90X2dlbmVzPW4oKSkgI+Wbs+S4reOBruaVsAoKCiMjIyMjIyMKcHJpbnQoIn5+IEgzcDNfQlJCIH5+IikKZm9yIChpIGluIDE6bGVuZ3RoKFRpbWVfbGlzdCkpIHsKICBwcmludChwYXN0ZSgiLS0tLS0iLFRpbWVfbGlzdFtpXSwgIi0tLSBIM3AzY2x1c3RlckFsbDogSDNwM19CUkIgLS0iKSkKICBjb3JyX0gzcDNjbHVzMyA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBmaWx0ZXIoKHRpbWU9PVRpbWVfbGlzdFtpXSkpCiAgdHR0dHR0IDwtIGNvci50ZXN0KGNvcnJfSDNwM2NsdXMzJEgzcDMsIGNvcnJfSDNwM2NsdXMzJEJSQiwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgI3ByaW50KHR0dHR0dCkKICAKICBpZiAoaSA9PSAxKSB7IAogICAgICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIHVubGlzdCh0dHR0dHQpICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiQ29yX3Rlc3QiKSAgJT4lIGFzX3RpYmJsZSgpICU+JSBkcGx5cjo6cmVuYW1lKFZhbHVlPSIuIikgJT4lIG11dGF0ZSh0aW1lPVRpbWVfbGlzdFtpXSx0YXJnZXQ9IkgzcDNjbHVzM0FsbCIsQ29tcGFyZT1wYXN0ZSgiSDNwMyIsICJCUkIiLHNlcD0iXyIpKQogIH0gCiAgZWxzZSB7CiAgICAgIHNzc3NzcyA8LSB1bmxpc3QodHR0dHR0KSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIkNvcl90ZXN0IikgICU+JSBhc190aWJibGUoKSAlPiUgZHBseXI6OnJlbmFtZShWYWx1ZT0iLiIpICAlPiUgbXV0YXRlKHRpbWU9VGltZV9saXN0W2ldLHRhcmdldD0iSDNwM2NsdXMzQWxsIixDb21wYXJlPXBhc3RlKCJIM3AzIiwgIkJSQiIsc2VwPSJfIikpCiAgICAgIGNvcnRlc3RfcmVzdWx0X3MgPC0gYmluZF9yb3dzKGNvcnRlc3RfcmVzdWx0X3MsIHNzc3NzcykKICB9Cn0KCnByaW50KCJ+fiBIM0s0bWUzX0JSQiB+fiIpCmZvciAoaSBpbiAxOmxlbmd0aChUaW1lX2xpc3QpKSB7CiAgcHJpbnQocGFzdGUoIi0tLS0tIixUaW1lX2xpc3RbaV0sICItLS0gSDNwM2NsdXN0ZXJBbGw6IEgzSzRtZTNfQlJCIC0tIikpCiAgY29ycl9IM3AzY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKCh0aW1lPT1UaW1lX2xpc3RbaV0pKQogIHR0dHR0dCA8LSBjb3IudGVzdChjb3JyX0gzcDNjbHVzMyRIM0s0bWUzLCBjb3JyX0gzcDNjbHVzMyRCUkIsIG1ldGhvZD0ic3BlYXJtYW4iKQogICNwcmludCh0dHR0dHQpCiAgCiAgc3Nzc3NzIDwtIHVubGlzdCh0dHR0dHQpICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiQ29yX3Rlc3QiKSAgJT4lIGFzX3RpYmJsZSgpICU+JSBkcGx5cjo6cmVuYW1lKFZhbHVlPSIuIikgICU+JSBtdXRhdGUodGltZT1UaW1lX2xpc3RbaV0sdGFyZ2V0PSJIM3AzY2x1czNBbGwiLENvbXBhcmU9cGFzdGUoIkgzSzRtZTMiLCAiQlJCIixzZXA9Il8iKSkKICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCn0KCnByaW50KCJ+fiBIM0syN2FjX0JSQiB+fiIpCmZvciAoaSBpbiAxOmxlbmd0aChUaW1lX2xpc3QpKSB7CiAgcHJpbnQocGFzdGUoIi0tLS0tIixUaW1lX2xpc3RbaV0sICItLS0gSDNwM2NsdXN0ZXJBbGw6IEgzSzI3YWNfQlJCIC0tIikpCiAgY29ycl9IM3AzY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKCh0aW1lPT1UaW1lX2xpc3RbaV0pKQogIHR0dHR0dCA8LSBjb3IudGVzdChjb3JyX0gzcDNjbHVzMyRIM0syN2FjLCBjb3JyX0gzcDNjbHVzMyRCUkIsIG1ldGhvZD0ic3BlYXJtYW4iKQogICNwcmludCh0dHR0dHQpCiAgCgogIHNzc3NzcyA8LSB1bmxpc3QodHR0dHR0KSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIkNvcl90ZXN0IikgICU+JSBhc190aWJibGUoKSAlPiUgZHBseXI6OnJlbmFtZShWYWx1ZT0iLiIpICAlPiUgbXV0YXRlKHRpbWU9VGltZV9saXN0W2ldLHRhcmdldD0iSDNwM2NsdXMzQWxsIixDb21wYXJlPXBhc3RlKCJIM0syN2FjIiwgIkJSQiIsc2VwPSJfIikpCiAgY29ydGVzdF9yZXN1bHRfcyA8LSBiaW5kX3Jvd3MoY29ydGVzdF9yZXN1bHRfcywgc3Nzc3NzKQp9CgpwcmludCgifn4gSDNLMjdtZTNfQlJCIH5+IikKZm9yIChpIGluIDE6bGVuZ3RoKFRpbWVfbGlzdCkpIHsKICBwcmludChwYXN0ZSgiLS0tLS0iLFRpbWVfbGlzdFtpXSwgIi0tLSBIM3AzY2x1c3RlckFsbDogSDNLMjdtZTNfQlJCIC0tIikpCiAgY29ycl9IM3AzY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKCh0aW1lPT1UaW1lX2xpc3RbaV0pKQogIHR0dHR0dCA8LSBjb3IudGVzdChjb3JyX0gzcDNjbHVzMyRIM0syN21lMywgY29ycl9IM3AzY2x1czMkQlJCLCBtZXRob2Q9InNwZWFybWFuIikKICAjcHJpbnQodHR0dHR0KQogIAoKICBzc3Nzc3MgPC0gdW5saXN0KHR0dHR0dCkgICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJDb3JfdGVzdCIpICAlPiUgYXNfdGliYmxlKCkgJT4lIGRwbHlyOjpyZW5hbWUoVmFsdWU9Ii4iKSAgJT4lIG11dGF0ZSh0aW1lPVRpbWVfbGlzdFtpXSx0YXJnZXQ9IkgzcDNjbHVzM0FsbCIsQ29tcGFyZT1wYXN0ZSgiSDNLMjdtZTMiLCAiQlJCIixzZXA9Il8iKSkKICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCn0KCnByaW50KCJ+fiBBVEFDX0JSQiB+fiIpCmZvciAoaSBpbiAxOmxlbmd0aChUaW1lX2xpc3QpKSB7CgogIGlmICgoaSA9PSAxKXwoaSA9PSA0KSkgeyAKICAgIHByaW50KHBhc3RlKCItLS0tLSIsVGltZV9saXN0W2ldLCAiLS0tIEgzcDNjbHVzdGVyQWxsOiBBVEFDX0JSQiAtLSIpKQogICAgY29ycl9IM3AzY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKCh0aW1lPT1UaW1lX2xpc3RbaV0pKQogICAgdHR0dHR0IDwtIGNvci50ZXN0KGNvcnJfSDNwM2NsdXMzJEFUQUMsIGNvcnJfSDNwM2NsdXMzJEJSQiwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgICAjcHJpbnQodHR0dHR0KQoKICAgIHNzc3NzcyA8LSB1bmxpc3QodHR0dHR0KSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIkNvcl90ZXN0IikgICU+JSBhc190aWJibGUoKSAlPiUgZHBseXI6OnJlbmFtZShWYWx1ZT0iLiIpICAlPiUgbXV0YXRlKHRpbWU9VGltZV9saXN0W2ldLHRhcmdldD0iSDNwM2NsdXMzQWxsIixDb21wYXJlPXBhc3RlKCJBVEFDIiwgIkJSQiIsc2VwPSJfIikpCiAgICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCiAgfSAKfQoKcHJpbnQoIn5+IEgzcDNfQVRBQyB+fiIpCmZvciAoaSBpbiAxOmxlbmd0aChUaW1lX2xpc3QpKSB7CgogIGlmICgoaSA9PSAxKXwoaSA9PSA0KSkgeyAKICAgIHByaW50KHBhc3RlKCItLS0tLSIsVGltZV9saXN0W2ldLCAiLS0tIEgzcDNjbHVzdGVyQWxsOiBIM3AzX0FUQUMgLS0iKSkKICAgIGNvcnJfSDNwM2NsdXMzIDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZpbHRlcigodGltZT09VGltZV9saXN0W2ldKSkKICAgIHR0dHR0dCA8LSBjb3IudGVzdChjb3JyX0gzcDNjbHVzMyRIM3AzLCBjb3JyX0gzcDNjbHVzMyRBVEFDLCBtZXRob2Q9InNwZWFybWFuIikKICAgICNwcmludCh0dHR0dHQpCgogICAgc3Nzc3NzIDwtIHVubGlzdCh0dHR0dHQpICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiQ29yX3Rlc3QiKSAgJT4lIGFzX3RpYmJsZSgpICU+JSBkcGx5cjo6cmVuYW1lKFZhbHVlPSIuIikgICU+JSBtdXRhdGUodGltZT1UaW1lX2xpc3RbaV0sdGFyZ2V0PSJIM3AzY2x1czNBbGwiLENvbXBhcmU9cGFzdGUoIkgzcDMiLCAiQVRBQyIsc2VwPSJfIikpCiAgICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCiAgfSAKfQoKCmNvcnRlc3RfcmVzdWx0X3NfSDNwM2NsdXMzQWxsIDwtIGNvcnRlc3RfcmVzdWx0X3MgJT4lIGdyb3VwX2J5KHRhcmdldCx0aW1lLENvbXBhcmUpICU+JSBzcHJlYWQoa2V5PSJDb3JfdGVzdCIsdmFsdWU9VmFsdWUpICAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwgIjBoIiwiMjRoIiwiNDhoIikpKSAlPiUgYXJyYW5nZSh0aW1lKQoKY29ydGVzdF9yZXN1bHRfc19IM3AzY2x1czNBbGwgPC0gY29ydGVzdF9yZXN1bHRfc19IM3AzY2x1czNBbGwgJT4lIGxlZnRfam9pbihDb3VudF9GQ19jdXRvZmZfSDNwM2NsdXMzKQpwcmludChjb3J0ZXN0X3Jlc3VsdF9zX0gzcDNjbHVzM0FsbCkKCmNvcnRlc3RfcmVzdWx0X3NfSDNwM2NsdXMzQWxsICU+JSByZWFkcjo6d3JpdGVfY3N2KCIuL2xvZzJGQy90YWJsZXMvQ29ydGVzdF9yZXN1bHRfc3BlYXJtYW5fSDNwM2NsdXMzQWxsLmNzdiIpCgoKYGBgCgoKCgoKYGBge3IgY29ycmUgSDNwMyBjbHVzdGVyMyBCUkIgY2x1c3RlcjMgVUktNDhoIEgzcDNfQlJCIHNwZWFybWFufQoKVGltZV9saXN0IDwtIGMoIlVJIiwiMGgiLCIyNGgiLCI0OGgiKQpDb3VudF9GQ19jdXRvZmZfSDNwM2NsdXMzX0JSQmNsdXMzIDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZfZ2VuZV9CUkJjbHVzMyAlPiUgdW5ncm91cCgpICU+JSBncm91cF9ieSh0aW1lKSAlPiUgc3VtbWFyaXNlKFBsb3RfZ2VuZXM9bigpKSAj5Zuz5Lit44Gu5pWwKEJSQiBERUcgY2x1c3RlcjPjga7jgb8pCgoKCiMjIyMjIyMKcHJpbnQoIn5+IEgzcDNfQlJCIH5+IikKZm9yIChpIGluIDE6bGVuZ3RoKFRpbWVfbGlzdCkpIHsKICBwcmludChwYXN0ZSgiLS0tLS0iLFRpbWVfbGlzdFtpXSwgIi0tLSBIM3AzY2x1czNCUkJjbHVzMzogSDNwM19CUkIgLS0iKSkKICBjb3JyX0gzcDNjbHVzM0JSQmNsdXMzIDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZpbHRlcihCUkJERUdjbHVzdGVyPT0iMyIpJT4lIGZpbHRlcigodGltZT09VGltZV9saXN0W2ldKSkKICB0dHR0dHQgPC0gY29yLnRlc3QoY29ycl9IM3AzY2x1czNCUkJjbHVzMyRIM3AzLCBjb3JyX0gzcDNjbHVzM0JSQmNsdXMzJEJSQiwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgI3ByaW50KHR0dHR0dCkKICAKICBpZiAoaSA9PSAxKSB7IAogICAgICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIHVubGlzdCh0dHR0dHQpICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiQ29yX3Rlc3QiKSAgJT4lIGFzX3RpYmJsZSgpICU+JSBkcGx5cjo6cmVuYW1lKFZhbHVlPSIuIikgJT4lIG11dGF0ZSh0aW1lPVRpbWVfbGlzdFtpXSx0YXJnZXQ9IkgzcDNjbHVzM0JSQmNsdXMzIixDb21wYXJlPXBhc3RlKCJIM3AzIiwgIkJSQiIsc2VwPSJfIikpCiAgfSAKICBlbHNlIHsKICAgICAgc3Nzc3NzIDwtIHVubGlzdCh0dHR0dHQpICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiQ29yX3Rlc3QiKSAgJT4lIGFzX3RpYmJsZSgpICU+JSBkcGx5cjo6cmVuYW1lKFZhbHVlPSIuIikgICU+JSBtdXRhdGUodGltZT1UaW1lX2xpc3RbaV0sdGFyZ2V0PSJIM3AzY2x1czNCUkJjbHVzMyIsQ29tcGFyZT1wYXN0ZSgiSDNwMyIsICJCUkIiLHNlcD0iXyIpKQogICAgICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCiAgfQp9CgpwcmludCgifn4gSDNLNG1lM19CUkIgfn4iKQpmb3IgKGkgaW4gMTpsZW5ndGgoVGltZV9saXN0KSkgewogIHByaW50KHBhc3RlKCItLS0tLSIsVGltZV9saXN0W2ldLCAiLS0tIEgzcDNjbHVzM0JSQmNsdXMzOiBIM0s0bWUzX0JSQiAtLSIpKQogIGNvcnJfSDNwM2NsdXMzQlJCY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKEJSQkRFR2NsdXN0ZXI9PSIzIiklPiUgZmlsdGVyKCh0aW1lPT1UaW1lX2xpc3RbaV0pKQogIHR0dHR0dCA8LSBjb3IudGVzdChjb3JyX0gzcDNjbHVzM0JSQmNsdXMzJEgzSzRtZTMsIGNvcnJfSDNwM2NsdXMzQlJCY2x1czMkQlJCLCBtZXRob2Q9InNwZWFybWFuIikKICAjcHJpbnQodHR0dHR0KQogIAogIHNzc3NzcyA8LSB1bmxpc3QodHR0dHR0KSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIkNvcl90ZXN0IikgICU+JSBhc190aWJibGUoKSAlPiUgZHBseXI6OnJlbmFtZShWYWx1ZT0iLiIpICAlPiUgbXV0YXRlKHRpbWU9VGltZV9saXN0W2ldLHRhcmdldD0iSDNwM2NsdXMzQlJCY2x1czMiLENvbXBhcmU9cGFzdGUoIkgzSzRtZTMiLCAiQlJCIixzZXA9Il8iKSkKICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCn0KCnByaW50KCJ+fiBIM0syN2FjX0JSQiB+fiIpCmZvciAoaSBpbiAxOmxlbmd0aChUaW1lX2xpc3QpKSB7CiAgcHJpbnQocGFzdGUoIi0tLS0tIixUaW1lX2xpc3RbaV0sICItLS0gSDNwM2NsdXMzQlJCY2x1czM6IEgzSzI3YWNfQlJCIC0tIikpCiAgY29ycl9IM3AzY2x1czNCUkJjbHVzMyA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBmaWx0ZXIoQlJCREVHY2x1c3Rlcj09IjMiKSU+JSBmaWx0ZXIoKHRpbWU9PVRpbWVfbGlzdFtpXSkpCiAgdHR0dHR0IDwtIGNvci50ZXN0KGNvcnJfSDNwM2NsdXMzQlJCY2x1czMkSDNLMjdhYywgY29ycl9IM3AzY2x1czNCUkJjbHVzMyRCUkIsIG1ldGhvZD0ic3BlYXJtYW4iKQogICNwcmludCh0dHR0dHQpCiAgCgogIHNzc3NzcyA8LSB1bmxpc3QodHR0dHR0KSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIkNvcl90ZXN0IikgICU+JSBhc190aWJibGUoKSAlPiUgZHBseXI6OnJlbmFtZShWYWx1ZT0iLiIpICAlPiUgbXV0YXRlKHRpbWU9VGltZV9saXN0W2ldLHRhcmdldD0iSDNwM2NsdXMzQlJCY2x1czMiLENvbXBhcmU9cGFzdGUoIkgzSzI3YWMiLCAiQlJCIixzZXA9Il8iKSkKICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCn0KCnByaW50KCJ+fiBIM0syN21lM19CUkIgfn4iKQpmb3IgKGkgaW4gMTpsZW5ndGgoVGltZV9saXN0KSkgewogIHByaW50KHBhc3RlKCItLS0tLSIsVGltZV9saXN0W2ldLCAiLS0tIEgzcDNjbHVzM0JSQmNsdXMzOiBIM0syN21lM19CUkIgLS0iKSkKICBjb3JyX0gzcDNjbHVzM0JSQmNsdXMzIDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZpbHRlcihCUkJERUdjbHVzdGVyPT0iMyIpJT4lIGZpbHRlcigodGltZT09VGltZV9saXN0W2ldKSkKICB0dHR0dHQgPC0gY29yLnRlc3QoY29ycl9IM3AzY2x1czNCUkJjbHVzMyRIM0syN21lMywgY29ycl9IM3AzY2x1czNCUkJjbHVzMyRCUkIsIG1ldGhvZD0ic3BlYXJtYW4iKQogICNwcmludCh0dHR0dHQpCiAgCgogIHNzc3NzcyA8LSB1bmxpc3QodHR0dHR0KSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIkNvcl90ZXN0IikgICU+JSBhc190aWJibGUoKSAlPiUgZHBseXI6OnJlbmFtZShWYWx1ZT0iLiIpICAlPiUgbXV0YXRlKHRpbWU9VGltZV9saXN0W2ldLHRhcmdldD0iSDNwM2NsdXMzQlJCY2x1czMiLENvbXBhcmU9cGFzdGUoIkgzSzI3bWUzIiwgIkJSQiIsc2VwPSJfIikpCiAgY29ydGVzdF9yZXN1bHRfcyA8LSBiaW5kX3Jvd3MoY29ydGVzdF9yZXN1bHRfcywgc3Nzc3NzKQp9CgpwcmludCgifn4gQVRBQ19CUkIgfn4iKQpmb3IgKGkgaW4gMTpsZW5ndGgoVGltZV9saXN0KSkgewoKICBpZiAoKGkgPT0gMSl8KGkgPT0gNCkpIHsgCiAgICBwcmludChwYXN0ZSgiLS0tLS0iLFRpbWVfbGlzdFtpXSwgIi0tLSBIM3AzY2x1czNCUkJjbHVzMzogQVRBQ19CUkIgLS0iKSkKICAgIGNvcnJfSDNwM2NsdXMzQlJCY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKEJSQkRFR2NsdXN0ZXI9PSIzIiklPiUgZmlsdGVyKCh0aW1lPT1UaW1lX2xpc3RbaV0pKQogICAgdHR0dHR0IDwtIGNvci50ZXN0KGNvcnJfSDNwM2NsdXMzQlJCY2x1czMkQVRBQywgY29ycl9IM3AzY2x1czNCUkJjbHVzMyRCUkIsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAgI3ByaW50KHR0dHR0dCkKCiAgICBzc3Nzc3MgPC0gdW5saXN0KHR0dHR0dCkgICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJDb3JfdGVzdCIpICAlPiUgYXNfdGliYmxlKCkgJT4lIGRwbHlyOjpyZW5hbWUoVmFsdWU9Ii4iKSAgJT4lIG11dGF0ZSh0aW1lPVRpbWVfbGlzdFtpXSx0YXJnZXQ9IkgzcDNjbHVzM0JSQmNsdXMzIixDb21wYXJlPXBhc3RlKCJBVEFDIiwgIkJSQiIsc2VwPSJfIikpCiAgICBjb3J0ZXN0X3Jlc3VsdF9zIDwtIGJpbmRfcm93cyhjb3J0ZXN0X3Jlc3VsdF9zLCBzc3Nzc3MpCiAgfSAKfQoKcHJpbnQoIn5+IEgzcDNfQVRBQyB+fiIpCmZvciAoaSBpbiAxOmxlbmd0aChUaW1lX2xpc3QpKSB7CgogIGlmICgoaSA9PSAxKXwoaSA9PSA0KSkgeyAKICAgIHByaW50KHBhc3RlKCItLS0tLSIsVGltZV9saXN0W2ldLCAiLS0tIEgzcDNjbHVzM0JSQmNsdXMzOiBIM3AzX0FUQUMgLS0iKSkKICAgIGNvcnJfSDNwM2NsdXMzQlJCY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKEJSQkRFR2NsdXN0ZXI9PSIzIiklPiUgZmlsdGVyKCh0aW1lPT1UaW1lX2xpc3RbaV0pKQogICAgdHR0dHR0IDwtIGNvci50ZXN0KGNvcnJfSDNwM2NsdXMzQlJCY2x1czMkSDNwMywgY29ycl9IM3AzY2x1czNCUkJjbHVzMyRBVEFDLCBtZXRob2Q9InNwZWFybWFuIikKICAgICNwcmludCh0dHR0dHQpCgogICAgc3Nzc3NzIDwtIHVubGlzdCh0dHR0dHQpICAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiQ29yX3Rlc3QiKSAgJT4lIGFzX3RpYmJsZSgpICU+JSBkcGx5cjo6cmVuYW1lKFZhbHVlPSIuIikgICU+JSBtdXRhdGUodGltZT1UaW1lX2xpc3RbaV0sdGFyZ2V0PSJIM3AzY2x1czNCUkJjbHVzMyIsQ29tcGFyZT1wYXN0ZSgiSDNwMyIsICJBVEFDIixzZXA9Il8iKSkKICAgIGNvcnRlc3RfcmVzdWx0X3MgPC0gYmluZF9yb3dzKGNvcnRlc3RfcmVzdWx0X3MsIHNzc3NzcykKICB9IAp9CgoKY29ydGVzdF9yZXN1bHRfc19IM3AzY2x1czNCUkJjbHVzMyA8LSBjb3J0ZXN0X3Jlc3VsdF9zICU+JSBncm91cF9ieSh0YXJnZXQsdGltZSxDb21wYXJlKSAlPiUgc3ByZWFkKGtleT0iQ29yX3Rlc3QiLHZhbHVlPVZhbHVlKSAgJT4lIG11dGF0ZSh0aW1lPWZhY3Rvcih0aW1lLCBjKCJVSSIsICIwaCIsIjI0aCIsIjQ4aCIpKSkgJT4lIGFycmFuZ2UodGltZSkKCmNvcnRlc3RfcmVzdWx0X3NfSDNwM2NsdXMzQlJCY2x1czMgPC0gY29ydGVzdF9yZXN1bHRfc19IM3AzY2x1czNCUkJjbHVzMyAlPiUgbGVmdF9qb2luKENvdW50X0ZDX2N1dG9mZl9IM3AzY2x1czNfQlJCY2x1czMpCnByaW50KGNvcnRlc3RfcmVzdWx0X3NfSDNwM2NsdXMzQlJCY2x1czMpCgpjb3J0ZXN0X3Jlc3VsdF9zX0gzcDNjbHVzM0JSQmNsdXMzICU+JSByZWFkcjo6d3JpdGVfY3N2KCIuL2xvZzJGQy90YWJsZXMvQ29ydGVzdF9yZXN1bHRzX3NwZWFybWFuX0gzcDNjbHVzM0JSQmNsdXMzLmNzdiIpCgoKYGBgCgoKYGBge3IgcmFuaywgZmlnLndpZHRoPTUsZmlnLmhlaWdodD0yfQoKCiMgQWxsCnJhbmtfY29ycl9IM3AzY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZ3JvdXBfYnkodGltZSkgJT4lIG11dGF0ZShyYW5rX0gzcDM9cmFuayhIM3AzKSwgcmFua19IM0s0bWUzPXJhbmsoSDNLNG1lMyksICByYW5rX0gzSzI3YWM9cmFuayhIM0syN2FjKSwgcmFua19IM0syN21lMz1yYW5rKEgzSzI3bWUzKSwgcmFua19BVEFDPXJhbmsoQVRBQyksIHJhbmtfQlJCPXJhbmsoQlJCKSkKCiNIM3AzY2x1czNCUkJjbHVzMwpyYW5rX2NvcnJfSDNwM2NsdXMzQlJCY2x1czMgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZmlsdGVyKEJSQkRFR2NsdXN0ZXI9PSIzIikgJT4lIGdyb3VwX2J5KHRpbWUpICU+JSBtdXRhdGUocmFua19IM3AzPXJhbmsoSDNwMyksIHJhbmtfSDNLNG1lMz1yYW5rKEgzSzRtZTMpLCAgcmFua19IM0syN2FjPXJhbmsoSDNLMjdhYyksIHJhbmtfSDNLMjdtZTM9cmFuayhIM0syN21lMyksIHJhbmtfQVRBQz1yYW5rKEFUQUMpLCByYW5rX0JSQj1yYW5rKEJSQikpCgoKCiMjIwpmY3Bsb3QgPC0gcmFua19jb3JyX0gzcDNjbHVzM0JSQmNsdXMzICAlPiUgZ2dwbG90KGFlcyh5PXJhbmtfQlJCLCB4PXJhbmtfSDNwMykpICArIGZhY2V0X3dyYXAofnRpbWUsbnJvdz0xLCBzY2FsZXMgPSAiZnJlZSIpICsgCiAgeGxpbSgwLCBOQSkgKyB5bGltKDAsIE5BKSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIHNpemU9MS4wKSt0aGVtZV9idygpICsgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSxheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsdmp1c3Q9MS4wKSwgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Iiwgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNSksc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSx0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpKQoKIysgeGxpbSgwLDYwKSArIHlsaW0oMCw2MCkKCgpmY3Bsb3QgPC0gZmNwbG90ICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNCUkJjbHVzMyxDb21wYXJlPT0iSDNwM19CUkIiKSxhZXMoeD0wLHk9NjAsbGFiZWw9cGFzdGUoc3ByaW50ZigiJTQuM2UiLCBlc3RpbWF0ZS5yaG8pLCIgICgiLFBsb3RfZ2VuZXMsIiAgZ2VuZXMpIiwgc2VwPSIiKSksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMi4wKQoKCiMrIHN0YXRfc21vb3RoKCkKIysgc3RhdF9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3VyID0gImJsYWNrIiwgc2l6ZSA9IDEpCiMrICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSwgc2UgPSBGQUxTRSkKCgpmY3Bsb3QKCgojcmFua19jb3JyX0gzcDNjbHVzM0JSQmNsdXMzIDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZpbHRlcihCUkJERUdjbHVzdGVyPT0iMyIpJT4lIGZpbHRlcigodGltZT09IjQ4aCIpKSAlPiUgbXV0YXRlKHJhbmtfSDNwMz1yYW5rKEgzcDMpLCByYW5rX0gzSzRtZTM9cmFuayhIM0s0bWUzKSwgIHJhbmtfSDNLMjdhYz1yYW5rKEgzSzI3YWMpLCByYW5rX0gzSzI3bWUzPXJhbmsoSDNLMjdtZTMpLCByYW5rX0FUQUM9cmFuayhBVEFDKSwgcmFua19CUkI9cmFuayhCUkIpKQoKI2Nvci50ZXN0KHJhbmtfY29ycl9IM3AzY2x1czNCUkJjbHVzMyRyYW5rX0gzcDMsIHJhbmtfY29ycl9IM3AzY2x1czNCUkJjbHVzMyRyYW5rX0JSQikKCgpgYGAKCmBgYHtyIGV4dHJhY3RSZXMzIG5vcm19CgojIyMg5Lim44Gz5pu/44GI44Gu44Gf44KBCgpncm91cHNfQlJCX2FyciA8LSBjKCJCUkJfVUlfRG94TWludXMiLCJCUkJfVUlfRG94UGx1cyIsIkJSQl8waF9Eb3hNaW51cyIsIkJSQl8waF9Eb3hQbHVzIiwiQlJCXzI0aF9Eb3hNaW51cyIsIkJSQl8yNGhfRG94UGx1cyIsIkJSQl80OGhfRG94TWludXMiLCJCUkJfNDhoX0RveFBsdXMiKQpncm91cHNfQVRBQ19hcnIgPC0gYygiQVRBQ19VSV9Eb3hNaW51cyIsIkFUQUNfVUlfRG94UGx1cyIsIkFUQUNfNDhoX0RveE1pbnVzIiwiQVRBQ180OGhfRG94UGx1cyIpCmdyb3Vwc19IM3AzX2FyciA8LSBjKCJIM3AzX1VJX0RveE1pbnVzIiwiSDNwM19VSV9Eb3hQbHVzIiwiSDNwM18waF9Eb3hNaW51cyIsIkgzcDNfMGhfRG94UGx1cyIsIkgzcDNfMjRoX0RveE1pbnVzIiwiSDNwM18yNGhfRG94UGx1cyIsIkgzcDNfNDhoX0RveE1pbnVzIiwiSDNwM180OGhfRG94UGx1cyIpCmdyb3Vwc19IM0s0bWUzX2FyciA8LSBjKCJIM0s0bWUzX1VJX0RveE1pbnVzIiwiSDNLNG1lM19VSV9Eb3hQbHVzIiwiSDNLNG1lM18waF9Eb3hNaW51cyIsIkgzSzRtZTNfMGhfRG94UGx1cyIsIkgzSzRtZTNfMjRoX0RveE1pbnVzIiwiSDNLNG1lM18yNGhfRG94UGx1cyIsIkgzSzRtZTNfNDhoX0RveE1pbnVzIiwiSDNLNG1lM180OGhfRG94UGx1cyIpCmdyb3Vwc19IM0syN2FjX2FyciA8LSBjKCJIM0syN2FjX1VJX0RveE1pbnVzIiwiSDNLMjdhY19VSV9Eb3hQbHVzIiwiSDNLMjdhY18waF9Eb3hNaW51cyIsIkgzSzI3YWNfMGhfRG94UGx1cyIsIkgzSzI3YWNfMjRoX0RveE1pbnVzIiwiSDNLMjdhY18yNGhfRG94UGx1cyIsIkgzSzI3YWNfNDhoX0RveE1pbnVzIiwiSDNLMjdhY180OGhfRG94UGx1cyIpCmdyb3Vwc19IM0syN21lM19hcnIgPC0gYygiSDNLMjdtZTNfVUlfRG94TWludXMiLCJIM0syN21lM19VSV9Eb3hQbHVzIiwiSDNLMjdtZTNfMGhfRG94TWludXMiLCJIM0syN21lM18waF9Eb3hQbHVzIiwiSDNLMjdtZTNfMjRoX0RveE1pbnVzIiwiSDNLMjdtZTNfMjRoX0RveFBsdXMiLCJIM0syN21lM180OGhfRG94TWludXMiLCJIM0syN21lM180OGhfRG94UGx1cyIpCgoKZ3JvdXB0X0JSQl9hcnIgPC0gYygiQlJCX0RveE1pbnVzIiwiQlJCX0RveFBsdXMiKQpncm91cHRfQVRBQ19hcnIgPC0gYygiQVRBQ19Eb3hNaW51cyIsIkFUQUNfRG94UGx1cyIpCmdyb3VwdF9IM3AzX2FyciA8LSBjKCJIM3AzX0RveE1pbnVzIiwiSDNwM19Eb3hQbHVzIikKZ3JvdXB0X0gzSzRtZTNfYXJyIDwtIGMoIkgzSzRtZTNfRG94TWludXMiLCJIM0s0bWUzX0RveFBsdXMiKQpncm91cHRfSDNLMjdhY19hcnIgPC0gYygiSDNLMjdhY19Eb3hNaW51cyIsIkgzSzI3YWNfRG94UGx1cyIpCmdyb3VwdF9IM0syN21lM19hcnIgPC0gYygiSDNLMjdtZTNfRG94TWludXMiLCJIM0syN21lM19Eb3hQbHVzIikKCgpnZ2dnX2xpc3QyIDwtIGMoImVuc19nZW5lIiwgImV4dF9nZW5lIiwgInRpbWUiLCJCUkJncm91cE1lYW4iLCAiSDNwM2NsdXN0ZXIiLCAiQlJCREVHY2x1c3RlciIsIGFsbF9vZihncm91cHRfSDNwM19hcnIpLGFsbF9vZihncm91cHRfSDNLNG1lM19hcnIpLGFsbF9vZihncm91cHRfSDNLMjdhY19hcnIpLGFsbF9vZihncm91cHRfSDNLMjdtZTNfYXJyKSxhbGxfb2YoZ3JvdXB0X0FUQUNfYXJyKSxhbGxfb2YoZ3JvdXB0X0JSQl9hcnIpKQoKZ2dnZ19saXN0MSA8LSBjKCJlbnNfZ2VuZSIsICJIM3AzY2x1c3RlciIsICJCUkJERUdjbHVzdGVyIixhbGxfb2YoZ3JvdXBzX0gzcDNfYXJyKSxhbGxfb2YoZ3JvdXBzX0gzSzRtZTNfYXJyKSxhbGxfb2YoZ3JvdXBzX0gzSzI3YWNfYXJyKSxhbGxfb2YoZ3JvdXBzX0gzSzI3bWUzX2FyciksYWxsX29mKGdyb3Vwc19BVEFDX2FyciksYWxsX29mKGdyb3Vwc19CUkJfYXJyKSkKCgojIyDlhajjgabntZDlkIgKCgpub3JtX2NoaWxhdGFjX2N1dG9mZiA8LSBub3JtX3Bsb3RsaXN0X2FsbCAgJT4lIGZpbHRlcihlbnNfZ2VuZSAlaW4lIG5vcm1fQlJCX2N1dG9mZiRlbnNfZ2VuZSkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsc2FtcGxlLGdyb3VwLHRpbWUsdHlwZSxzZXEscmVwLG5vcm1hbGl6ZWQpCm5vcm1fYnJiX2N1dG9mZiA8LSBub3JtX0JSQiAgJT4lIGZpbHRlcihlbnNfZ2VuZSAlaW4lIG5vcm1fQlJCX2N1dG9mZiRlbnNfZ2VuZSkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsc2FtcGxlLGdyb3VwLHRpbWUsdHlwZSxzZXEscmVwLG5vcm0pICU+JSByZW5hbWUobm9ybWFsaXplZD1ub3JtKQoKIyMg5YWo44Gm57WQ5ZCICm5vcm1fcGxvdGxpc3RfY3V0b2ZmIDwtIGJpbmRfcm93cyhub3JtX2NoaWxhdGFjX2N1dG9mZixub3JtX2JyYl9jdXRvZmYpICAlPiUgbXV0YXRlKHNlcT1mYWN0b3Ioc2VxLCBjKCJIM3AzIiwgIkgzSzRtZTMiLCJIM0syN2FjIiwiSDNLMjdtZTMiLCJBVEFDIiwiQlJCIikpKSAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwgIjBoIiwiMjRoIiwiNDhoIikpKSAjIENoSUwgJiBBVEFDICYgQlJCIChjdXQgb2ZmIOWFqOOBpikKCm5vcm1fdHlwZW1lYW5fY3V0b2ZmIDwtIG5vcm1fcGxvdGxpc3RfY3V0b2ZmICAlPiUgZ3JvdXBfYnkoZW5zX2dlbmUsZ3JvdXAsdGltZSx0eXBlLHNlcSkgJT4lIHN1bW1hcmlzZShUeXBlTWVhbj1tZWFuKG5vcm1hbGl6ZWQpKSAgJT4lIG11dGF0ZShzZXFfdHlwZT1wYXN0ZShzZXEsdHlwZSxzZXA9Il8iKSkKCnNwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZiA8LSBub3JtX3R5cGVtZWFuX2N1dG9mZiAlPiUgdW5ncm91cCgpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLHRpbWUsc2VxX3R5cGUsVHlwZU1lYW4pICAlPiUgbXV0YXRlKHNlcV90eXBlPWZhY3RvcihzZXFfdHlwZSwgYygiSDNwM19Eb3hNaW51cyIsIkgzcDNfRG94UGx1cyIsICJIM0s0bWUzX0RveE1pbnVzIiwiSDNLNG1lM19Eb3hQbHVzIiwiSDNLMjdhY19Eb3hNaW51cyIsIkgzSzI3YWNfRG94UGx1cyIsIkgzSzI3bWUzX0RveE1pbnVzIiwiSDNLMjdtZTNfRG94UGx1cyIsIkFUQUNfRG94TWludXMiLCJBVEFDX0RveFBsdXMiLCJCUkJfRG94TWludXMiLCJCUkJfRG94UGx1cyIpKSkgJT4lIGFycmFuZ2Uoc2VxX3R5cGUpICU+JSBzcHJlYWQoa2V5PXNlcV90eXBlLHZhbHVlPVR5cGVNZWFuKQoKc3ByZWFkX25vcm1fdHlwZW1lYW5fY3V0b2ZmIDwtIHNwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZiAlPiUgbGVmdF9qb2luKGRwbHlyOjpzZWxlY3Qobm9ybV9CUkJfY3V0b2ZmLCBlbnNfZ2VuZSwgZXh0X2dlbmUsIHRpbWUsIGdyb3VwTWVhbikgJT4lIGRwbHlyOjpyZW5hbWUoQlJCZ3JvdXBNZWFuPWdyb3VwTWVhbikpCgpucm93KHNwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZikKCnNwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZl9jbHVzIDwtIHNwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZiAlPiUgbGVmdF9qb2luKGRwbHlyOjpzZWxlY3QocnJyZXNfYWxsSDNwMyxlbnNfZ2VuZSxjbHVzdGVyKSkgJT4lIGRwbHlyOjpyZW5hbWUoSDNwM2NsdXN0ZXI9Y2x1c3RlcikgJT4lIGxlZnRfam9pbihkcGx5cjo6c2VsZWN0KGNsdXN0ZXJfQlJCbGlzdCxlbnNfZ2VuZSxjbHVzdGVyKSkgJT4lIGRwbHlyOjpyZW5hbWUoQlJCREVHY2x1c3Rlcj1jbHVzdGVyKSAgJT4lIGRwbHlyOjpzZWxlY3QoYWxsX29mKGdnZ2dfbGlzdDIpKQoKbnJvdyhzcHJlYWRfbm9ybV90eXBlbWVhbl9jdXRvZmZfY2x1cykKCiMjIyMjCgp0aW1lX25vcm1fdHlwZW1lYW5fY3V0b2ZmIDwtIG5vcm1fdHlwZW1lYW5fY3V0b2ZmICU+JSB1bmdyb3VwKCkgICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLGdyb3VwLFR5cGVNZWFuKSAlPiUgZ3JvdXBfYnkoZW5zX2dlbmUpICU+JSBzcHJlYWQoa2V5PWdyb3VwLHZhbHVlPVR5cGVNZWFuKQoKbnJvdyh0aW1lX25vcm1fdHlwZW1lYW5fY3V0b2ZmKQoKdGltZV9ub3JtX3R5cGVtZWFuX2N1dG9mZl9jbHVzIDwtIHRpbWVfbm9ybV90eXBlbWVhbl9jdXRvZmYgJT4lIGxlZnRfam9pbihkcGx5cjo6c2VsZWN0KHJycmVzX2FsbEgzcDMsZW5zX2dlbmUsY2x1c3RlcikpICU+JSBkcGx5cjo6cmVuYW1lKEgzcDNjbHVzdGVyPWNsdXN0ZXIpICU+JSBsZWZ0X2pvaW4oZHBseXI6OnNlbGVjdChjbHVzdGVyX0JSQmxpc3QsZW5zX2dlbmUsY2x1c3RlcikpICU+JSBkcGx5cjo6cmVuYW1lKEJSQkRFR2NsdXN0ZXI9Y2x1c3RlcikgJT4lIGRwbHlyOjpzZWxlY3QoYWxsX29mKGdnZ2dfbGlzdDEpKQoKCm5yb3codGltZV9ub3JtX3R5cGVtZWFuX2N1dG9mZl9jbHVzKQoKIyMjIyMKCmZpbGVuYW1lIDwtICIuL0NvcnJlbGF0aW9uL3RhYmxlcy9ub3JtVHlwZU1lYW5fQWxsX2N1dG9mZjEwLmNzdiIKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3Yoc3ByZWFkX25vcm1fdHlwZW1lYW5fY3V0b2ZmX2NsdXMsZmlsZW5hbWUpCmhlYWQoc3ByZWFkX25vcm1fdHlwZW1lYW5fY3V0b2ZmX2NsdXMpCm5yb3coc3ByZWFkX25vcm1fdHlwZW1lYW5fY3V0b2ZmX2NsdXMpCgoKCgoKZmlsZW5hbWUgPC0gIi4vQ29ycmVsYXRpb24vdGFibGVzL25vcm1UeXBlTWVhbl9BbGxfY3V0b2ZmMTBfX3RpbWV2ZXIuY3N2IgpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdih0aW1lX25vcm1fdHlwZW1lYW5fY3V0b2ZmX2NsdXMsZmlsZW5hbWUpCmhlYWQodGltZV9ub3JtX3R5cGVtZWFuX2N1dG9mZl9jbHVzKQpucm93KHRpbWVfbm9ybV90eXBlbWVhbl9jdXRvZmZfY2x1cykKCgoKCmBgYAoKYGBge3IgY29yciBub3JtIHRhYmxlfQojZl9nZW5lX0gzcDNjbHVzMyA8LSBmdW5jdGlvbih4KSB4ICU+JSBmaWx0ZXIoSDNwM2NsdXN0ZXI9PSIzIikKI2ZfZ2VuZV9CUkJjbHVzMyA8LSBmdW5jdGlvbih4KSB4ICU+JSBmaWx0ZXIoQlJCREVHY2x1c3Rlcj09IjMiKQojbGlzdF9nZW5lX3FwY3IgPC0gIGMoIkFjdGExIiwiTXloMyIsIlR0biIsIk15b2ciKQoKY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzIDwtIHRpbWVfbm9ybV90eXBlbWVhbl9jdXRvZmZfY2x1cyAgICU+JSB1bmdyb3VwKCkgJT4lIGZfZ2VuZV9IM3AzY2x1czMKbnJvdyhjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czMpCgpjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czNCUkJjbHVzMyA8LSB0aW1lX25vcm1fdHlwZW1lYW5fY3V0b2ZmX2NsdXMgICAlPiUgdW5ncm91cCgpICU+JSBmX2dlbmVfSDNwM2NsdXMzICU+JSBmX2dlbmVfQlJCY2x1czMKbnJvdyhjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czNCUkJjbHVzMykKCgoKIyMjIwoKY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzX2ZpbHRlciA8LSBzcHJlYWRfbm9ybV90eXBlbWVhbl9jdXRvZmZfY2x1cyAgJT4lIGZpbHRlcighaXMubmEoQlJCZ3JvdXBNZWFuKSkgICU+JSB1bmdyb3VwKCkgJT4lIGZfZ2VuZV9IM3AzY2x1czMKbnJvdyhjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czNfZmlsdGVyKQoKY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzQlJCY2x1czNfZmlsdGVyIDwtIHNwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZl9jbHVzICAlPiUgZmlsdGVyKCFpcy5uYShCUkJncm91cE1lYW4pKSAgJT4lIHVuZ3JvdXAoKSAlPiUgZl9nZW5lX0gzcDNjbHVzMyAlPiUgZl9nZW5lX0JSQmNsdXMzCm5yb3coY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzQlJCY2x1czNfZmlsdGVyKQoKY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzX2ZpbHRlciAlPiUgZ3JvdXBfYnkodGltZSkgJT4lIHN1bW1hcmlzZShjb3VudD1uKCkpCmNvcnJfdHlwZW1lYW5fY3V0b2ZmX0gzcDNjbHVzM0JSQmNsdXMzX2ZpbHRlciAlPiUgZ3JvdXBfYnkodGltZSkgJT4lIHN1bW1hcmlzZShjb3VudD1uKCkpCgojZmlsZW5hbWUgPC0gIi4vbG9nMkZDL3RhYmxlcy9TcHJlYWRfbG9nMkZDX0NoSUxBVEFDQlJCX2N1dG9mZjEwX193aXRoQ2x1c3Rlcl9fSDNwM2NsdXMzLmNzdiIKI3ByaW50KGZpbGVuYW1lKQojcmVhZHI6OndyaXRlX2NzdihzcHJlYWRfbm9ybV90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzLGZpbGVuYW1lKQoKCiNzcHJlYWRfbm9ybV90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzCiNzcHJlYWRfbm9ybV90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzICU+JSBmX2dlbmVfSDNwM2NsdXMzICU+JSBmX2dlbmVfQlJCY2x1czMKI3NwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZfZ2VuZV9IM3AzY2x1czMgJT4lIGZfZ2VuZV9CUkJjbHVzMyAlPiUgZmlsdGVyKGV4dF9nZW5lICVpbiUgbGlzdF9nZW5lX3FwY3IpCgojSDNwM2NsdXMzY3V0b2ZmIDwtIHNwcmVhZF9ub3JtX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSkgJT4lIHVuaXF1ZSgpICU+JSBucm93KCkgCiNIM3AzY2x1czNjdXRvZmZfYnJiY2x1czMgPC0gc3ByZWFkX25vcm1fdHlwZW1lYW5fY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZl9nZW5lX0JSQmNsdXMzICU+JSB1bmdyb3VwKCkgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUpICU+JSB1bmlxdWUoKSAlPiUgbnJvdygpCgojbnJvdyh6X0gzcDNjbHVzMykKI0gzcDNjbHVzM2N1dG9mZgojSDNwM2NsdXMzY3V0b2ZmX2JyYmNsdXMzCgpgYGAKCuOBhOOBmuOCjOOBi+OBpyBCUkIgbm9ybSAoZ3JvdXApID4gMTDjgpLmuoDjgZ/jgZnjgoLjga7jgafjg5fjg63jg4Pjg4gKCmBgYHtyIG5vcm0gY29ycnBsb3Qgbm9ybSB0eXBlbWVhbiB0aW1lLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9MTB9CgpsaWJyYXJ5KGNvcnJwbG90KQoKIyMjIyBjYWxjdWxhdGUgY29ycmVsYXRpb24KCnByaW50KCJHZW5lcyBsaXN0IikKbnJvdyhjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czMpCm5yb3coY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzQlJCY2x1czMpCgpteWRhdGEuY29yLkFsbC5hbGx0aW1lIDwtIGNvcnJfdHlwZW1lYW5fY3V0b2ZmX0gzcDNjbHVzMyAlPiUgdW5ncm91cCgpICU+JSBkcGx5cjo6c2VsZWN0KC0iZW5zX2dlbmUiLCAtIkgzcDNjbHVzdGVyIiwgLSJCUkJERUdjbHVzdGVyIikgJT4lIGNvcihtZXRob2QgPSBjKCJzcGVhcm1hbiIpKQpteWRhdGEuY29yLkJSQmNsdXMzLmFsbHRpbWUgPC0gY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzQlJCY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZHBseXI6OnNlbGVjdCgtImVuc19nZW5lIiwgLSJIM3AzY2x1c3RlciIsIC0iQlJCREVHY2x1c3RlciIpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKCgpjb3JfQWxsX2FsbHRpbWUgPC0gYXMuZGF0YS5mcmFtZShteWRhdGEuY29yLkFsbC5hbGx0aW1lKSAlPiUgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImdyb3VwIikgJT4lIGFzX3RpYmJsZSAKY29yX0JSQmNsdXMzX2FsbHRpbWUgPC0gYXMuZGF0YS5mcmFtZShteWRhdGEuY29yLkJSQmNsdXMzLmFsbHRpbWUpICU+JSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiZ3JvdXAiKSAlPiUgYXNfdGliYmxlIAoKIyMjIwoKCnRpdGxlXzEgPC0gcGFzdGUoIkgzLjMgQ2x1c3RlcjMgJiBCUkIgREVHIENsdXN0ZXIzOiIsbnJvdyhjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czNCUkJjbHVzMyksImdlbmVzIixzZXA9IiAiKQp0aXRsZV8yIDwtIHBhc3RlKCJIMy4zIENsdXN0ZXIzOiIsbnJvdyhjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czMpLCJnZW5lcyIsc2VwPSIgIikKCgpicmVha3NMaXN0ID0gc2VxKC0xLCAxLCBieSA9IDAuMDUpCkNvbG9yX19hMCA8LSByZXYoYnJld2VyLnBhbChuID0gMTEsIG5hbWUgPSAiUmRZbEJ1IikpCkNvbG9yX19hIDwtIGNvbG9yUmFtcFBhbGV0dGUoQ29sb3JfX2EwKShsZW5ndGgoYnJlYWtzTGlzdCkpCgoKZ2Fwc18xIDwtIGMoOCwxNiwyNCwzMiwzNikKCgoKcGhlYXRtYXA6OnBoZWF0bWFwKG15ZGF0YS5jb3IuQlJCY2x1czMuYWxsdGltZSwgbWFpbiA9IHRpdGxlXzEsIHNjYWxlID0gIm5vbmUiLCBjb2xvciA9IENvbG9yX19hLGJyZWFrcyA9IGJyZWFrc0xpc3QsIGJvcmRlcl9jb2xvcj1OQSkKcGhlYXRtYXA6OnBoZWF0bWFwKG15ZGF0YS5jb3IuQWxsLmFsbHRpbWUsIG1haW4gPSB0aXRsZV8yLCBzY2FsZSA9ICJub25lIiwgY29sb3IgPSBDb2xvcl9fYSxicmVha3MgPSBicmVha3NMaXN0LCBib3JkZXJfY29sb3I9TkEpCgpwaGVhdG1hcDo6cGhlYXRtYXAobXlkYXRhLmNvci5CUkJjbHVzMy5hbGx0aW1lLCBtYWluID0gdGl0bGVfMSwgc2NhbGUgPSAibm9uZSIsIGNvbG9yID0gQ29sb3JfX2EsYnJlYWtzID0gYnJlYWtzTGlzdCwgYm9yZGVyX2NvbG9yPU5BLCBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgY2x1c3Rlcl9jb2xzID0gRkFMU0UsIGdhcHNfY29sPWdhcHNfMSwgZ2Fwc19yb3c9Z2Fwc18xKQpwaGVhdG1hcDo6cGhlYXRtYXAobXlkYXRhLmNvci5BbGwuYWxsdGltZSwgbWFpbiA9IHRpdGxlXzIsIHNjYWxlID0gIm5vbmUiLCBjb2xvciA9IENvbG9yX19hLGJyZWFrcyA9IGJyZWFrc0xpc3QsIGJvcmRlcl9jb2xvcj1OQSwgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFLCBnYXBzX2NvbD1nYXBzXzEsIGdhcHNfcm93PWdhcHNfMSkKCgpjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLmFsbHRpbWUsIGRpYWcgPSBGQUxTRSwgY29sID0gQ29sb3JfX2EpCmNvcnJwbG90KG15ZGF0YS5jb3IuQWxsLmFsbHRpbWUsIGRpYWcgPSBGQUxTRSwgY29sID0gQ29sb3JfX2EpCgoKIyMjIyMKCmZpbGVuYW1lIDwtICIuL0NvcnJlbGF0aW9uL3RhYmxlcy9Db3J0ZXN0X25vcm1UeXBlTWVhbl9zcGVhcm1hbl9IM3AzY2x1czNBbGxfY3V0b2ZmMTBfX3RpbWV2ZXIuY3N2IgpwcmludChmaWxlbmFtZSkKcmVhZHI6OndyaXRlX2Nzdihjb3JfQWxsX2FsbHRpbWUsZmlsZW5hbWUpCnByaW50KGNvcl9BbGxfYWxsdGltZSkKbnJvdyhjb3JfQWxsX2FsbHRpbWUpCgoKZmlsZW5hbWUgPC0gIi4vQ29ycmVsYXRpb24vdGFibGVzL0NvcnRlc3Rfbm9ybVR5cGVNZWFuX3NwZWFybWFuX0gzcDNjbHVzM0JSQmNsdXMzX2N1dG9mZjEwX190aW1ldmVyLmNzdiIKcHJpbnQoZmlsZW5hbWUpCnJlYWRyOjp3cml0ZV9jc3YoY29yX0JSQmNsdXMzX2FsbHRpbWUsZmlsZW5hbWUpCnByaW50KGNvcl9CUkJjbHVzM19hbGx0aW1lKQoKI2NvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuYWxsdGltZSwgZGlhZyA9IEZBTFNFLCB0eXBlID0gInVwcGVyIiwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCiNjb3JycGxvdChteWRhdGEuY29yLkFsbC5hbGx0aW1lLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAibG93ZXIiLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuYWxsdGltZSwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLmFsbHRpbWUsIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCgoKYGBgCgpgYGB7ciBub3JtIGNvcnJwbG90IG5vcm0gdHlwZW1lYW4gdGltZS0yLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9MTB9CgojIyDooajnpLrjg6rjgrnjg4gKZ2dnZ19wbG90X2Nvcmxpc3QgPC0gYyhhbGxfb2YoZ3JvdXBzX0gzcDNfYXJyKSxhbGxfb2YoZ3JvdXBzX0gzSzRtZTNfYXJyKSxhbGxfb2YoZ3JvdXBzX0gzSzI3YWNfYXJyKSxhbGxfb2YoZ3JvdXBzX0JSQl9hcnIpKQoKCmNvcl9BbGxfYWxsdGltZV9zZWxlY3QgPC0gY29yX0FsbF9hbGx0aW1lICU+JSBkcGx5cjo6c2VsZWN0KGdyb3VwLCBhbGxfb2YoZ2dnZ19wbG90X2Nvcmxpc3QpKSAlPiUgZmlsdGVyKGdyb3VwICVpbiUgZ2dnZ19wbG90X2Nvcmxpc3QpCm1hdF9jb3JfQWxsX2FsbHRpbWVfc2VsZWN0IDwtIGNvcl9BbGxfYWxsdGltZV9zZWxlY3QgJT4lIGRwbHlyOjpzZWxlY3QoLWdyb3VwKSAlPiUgYXMubWF0cml4KCkKcm93bmFtZXMobWF0X2Nvcl9BbGxfYWxsdGltZV9zZWxlY3QpIDwtIGNvcl9BbGxfYWxsdGltZV9zZWxlY3QkZ3JvdXAKCgpjb3JfQlJCY2x1czNfYWxsdGltZV9zZWxlY3QgPC0gY29yX0JSQmNsdXMzX2FsbHRpbWUgJT4lIGRwbHlyOjpzZWxlY3QoZ3JvdXAsIGFsbF9vZihnZ2dnX3Bsb3RfY29ybGlzdCkpICU+JSBmaWx0ZXIoZ3JvdXAgJWluJSBnZ2dnX3Bsb3RfY29ybGlzdCkKbWF0X2Nvcl9CUkJjbHVzM19hbGx0aW1lX3NlbGVjdCA8LSBjb3JfQlJCY2x1czNfYWxsdGltZV9zZWxlY3QgJT4lIGRwbHlyOjpzZWxlY3QoLWdyb3VwKSAlPiUgYXMubWF0cml4KCkKcm93bmFtZXMobWF0X2Nvcl9CUkJjbHVzM19hbGx0aW1lX3NlbGVjdCkgPC0gY29yX0JSQmNsdXMzX2FsbHRpbWVfc2VsZWN0JGdyb3VwCgpnYXBzXzIgPC0gYyg4LDE2LDI0KQoKIyMjIyBwbG90IChzZWxlY3Qgb25seSkKCiNicmVha3NMaXN0ID0gc2VxKC0xLCAxLCBieSA9IDAuMDUpCiNDb2xvcl9fYTAgPC0gcmV2KGJyZXdlci5wYWwobiA9IDExLCBuYW1lID0gIlJkWWxCdSIpKQojQ29sb3JfX2EgPC0gY29sb3JSYW1wUGFsZXR0ZShDb2xvcl9fYTApKGxlbmd0aChicmVha3NMaXN0KSkKCnBoZWF0bWFwOjpwaGVhdG1hcChtYXRfY29yX0JSQmNsdXMzX2FsbHRpbWVfc2VsZWN0LCBtYWluID0gdGl0bGVfMSwgc2NhbGUgPSAibm9uZSIsIGNvbG9yID0gQ29sb3JfX2EsYnJlYWtzID0gYnJlYWtzTGlzdCwgYm9yZGVyX2NvbG9yPU5BKQpwaGVhdG1hcDo6cGhlYXRtYXAobWF0X2Nvcl9BbGxfYWxsdGltZV9zZWxlY3QsIG1haW4gPSB0aXRsZV8yLCBzY2FsZSA9ICJub25lIiwgY29sb3IgPSBDb2xvcl9fYSxicmVha3MgPSBicmVha3NMaXN0LCBib3JkZXJfY29sb3I9TkEpCgpwaGVhdG1hcDo6cGhlYXRtYXAobWF0X2Nvcl9CUkJjbHVzM19hbGx0aW1lX3NlbGVjdCwgbWFpbiA9IHRpdGxlXzEsIHNjYWxlID0gIm5vbmUiLCBjb2xvciA9IENvbG9yX19hLGJyZWFrcyA9IGJyZWFrc0xpc3QsIGJvcmRlcl9jb2xvcj1OQSwgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFLCBnYXBzX2NvbD1nYXBzXzIsIGdhcHNfcm93PWdhcHNfMikKcGhlYXRtYXA6OnBoZWF0bWFwKG1hdF9jb3JfQWxsX2FsbHRpbWVfc2VsZWN0LCBtYWluID0gdGl0bGVfMiwgc2NhbGUgPSAibm9uZSIsIGNvbG9yID0gQ29sb3JfX2EsYnJlYWtzID0gYnJlYWtzTGlzdCwgYm9yZGVyX2NvbG9yPU5BLCBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgY2x1c3Rlcl9jb2xzID0gRkFMU0UsIGdhcHNfY29sPWdhcHNfMiwgZ2Fwc19yb3c9Z2Fwc18yKQoKCmNvcnJwbG90KG1hdF9jb3JfQlJCY2x1czNfYWxsdGltZV9zZWxlY3QsIGRpYWcgPSBGQUxTRSwgY29sID0gQ29sb3JfX2EpCmNvcnJwbG90KG1hdF9jb3JfQWxsX2FsbHRpbWVfc2VsZWN0LCBkaWFnID0gRkFMU0UsIGNvbCA9IENvbG9yX19hKQoKYGBgCgoKCiAgCmBgYHtyIG5vcm0gY29ycnBsb3Qgbm9ybSB0eXBlbWVhbiB0aW1lLTMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMH0KCmdyb3Vwc19VSV9hcnIgPC0gYygKICAiSDNwM19VSV9Eb3hNaW51cyIsIkgzcDNfVUlfRG94UGx1cyIsCiAgIkgzSzRtZTNfVUlfRG94TWludXMiLCJIM0s0bWUzX1VJX0RveFBsdXMiLAogICJIM0syN2FjX1VJX0RveE1pbnVzIiwiSDNLMjdhY19VSV9Eb3hQbHVzIiwKICAiSDNLMjdtZTNfVUlfRG94TWludXMiLCJIM0syN21lM19VSV9Eb3hQbHVzIiwKICAiQVRBQ19VSV9Eb3hNaW51cyIsIkFUQUNfVUlfRG94UGx1cyIsCiAgIkJSQl9VSV9Eb3hNaW51cyIsIkJSQl9VSV9Eb3hQbHVzIikKCgpncm91cHNfMGhfYXJyIDwtIGMoCiAgIkgzcDNfMGhfRG94TWludXMiLCJIM3AzXzBoX0RveFBsdXMiLAogICJIM0s0bWUzXzBoX0RveE1pbnVzIiwiSDNLNG1lM18waF9Eb3hQbHVzIiwKICAiSDNLMjdhY18waF9Eb3hNaW51cyIsIkgzSzI3YWNfMGhfRG94UGx1cyIsCiAgIkgzSzI3bWUzXzBoX0RveE1pbnVzIiwiSDNLMjdtZTNfMGhfRG94UGx1cyIsCiAgIkJSQl8waF9Eb3hNaW51cyIsIkJSQl8waF9Eb3hQbHVzIikKCmdyb3Vwc18yNGhfYXJyIDwtIGMoCiAgIkgzcDNfMjRoX0RveE1pbnVzIiwiSDNwM18yNGhfRG94UGx1cyIsCiAgIkgzSzRtZTNfMjRoX0RveE1pbnVzIiwiSDNLNG1lM18yNGhfRG94UGx1cyIsCiAgIkgzSzI3YWNfMjRoX0RveE1pbnVzIiwiSDNLMjdhY18yNGhfRG94UGx1cyIsCiAgIkgzSzI3bWUzXzI0aF9Eb3hNaW51cyIsIkgzSzI3bWUzXzI0aF9Eb3hQbHVzIiwKICAiQlJCXzI0aF9Eb3hNaW51cyIsIkJSQl8yNGhfRG94UGx1cyIpCiAgCmdyb3Vwc180OGhfYXJyIDwtIGMoCiAgIkgzcDNfNDhoX0RveE1pbnVzIiwiSDNwM180OGhfRG94UGx1cyIsCiAgIkgzSzRtZTNfNDhoX0RveE1pbnVzIiwiSDNLNG1lM180OGhfRG94UGx1cyIsCiAgIkgzSzI3YWNfNDhoX0RveE1pbnVzIiwiSDNLMjdhY180OGhfRG94UGx1cyIsCiAgIkgzSzI3bWUzXzQ4aF9Eb3hNaW51cyIsIkgzSzI3bWUzXzQ4aF9Eb3hQbHVzIiwKICAiQVRBQ180OGhfRG94TWludXMiLCJBVEFDXzQ4aF9Eb3hQbHVzIiwKICAiQlJCXzQ4aF9Eb3hNaW51cyIsIkJSQl80OGhfRG94UGx1cyIpCgoKZ3JvdXBzX1VJX2Fycl9zIDwtIGMoCiAgIkgzcDNfVUlfRG94TWludXMiLCJIM3AzX1VJX0RveFBsdXMiLAogICJIM0s0bWUzX1VJX0RveE1pbnVzIiwiSDNLNG1lM19VSV9Eb3hQbHVzIiwKICAiSDNLMjdhY19VSV9Eb3hNaW51cyIsIkgzSzI3YWNfVUlfRG94UGx1cyIsCiAgIkJSQl9VSV9Eb3hNaW51cyIsIkJSQl9VSV9Eb3hQbHVzIikKCgpncm91cHNfMGhfYXJyX3MgPC0gYygKICAiSDNwM18waF9Eb3hNaW51cyIsIkgzcDNfMGhfRG94UGx1cyIsCiAgIkgzSzRtZTNfMGhfRG94TWludXMiLCJIM0s0bWUzXzBoX0RveFBsdXMiLAogICJIM0syN2FjXzBoX0RveE1pbnVzIiwiSDNLMjdhY18waF9Eb3hQbHVzIiwKICAiQlJCXzBoX0RveE1pbnVzIiwiQlJCXzBoX0RveFBsdXMiKQoKZ3JvdXBzXzI0aF9hcnJfcyA8LSBjKAogICJIM3AzXzI0aF9Eb3hNaW51cyIsIkgzcDNfMjRoX0RveFBsdXMiLAogICJIM0s0bWUzXzI0aF9Eb3hNaW51cyIsIkgzSzRtZTNfMjRoX0RveFBsdXMiLAogICJIM0syN2FjXzI0aF9Eb3hNaW51cyIsIkgzSzI3YWNfMjRoX0RveFBsdXMiLAogICJCUkJfMjRoX0RveE1pbnVzIiwiQlJCXzI0aF9Eb3hQbHVzIikKICAKZ3JvdXBzXzQ4aF9hcnJfcyA8LSBjKAogICJIM3AzXzQ4aF9Eb3hNaW51cyIsIkgzcDNfNDhoX0RveFBsdXMiLAogICJIM0s0bWUzXzQ4aF9Eb3hNaW51cyIsIkgzSzRtZTNfNDhoX0RveFBsdXMiLAogICJIM0syN2FjXzQ4aF9Eb3hNaW51cyIsIkgzSzI3YWNfNDhoX0RveFBsdXMiLAogICJCUkJfNDhoX0RveE1pbnVzIiwiQlJCXzQ4aF9Eb3hQbHVzIikKCgojIyDooajnpLrjg6rjgrnjg4gKZ2dnZ19wbG90X2Nvcmxpc3RfdGltZSA8LSBjKGFsbF9vZihncm91cHNfVUlfYXJyX3MpLGFsbF9vZihncm91cHNfMGhfYXJyX3MpLGFsbF9vZihncm91cHNfMjRoX2Fycl9zKSxhbGxfb2YoZ3JvdXBzXzQ4aF9hcnJfcykpCgoKY29yX0FsbF9hbGx0aW1lX3NlbGVjdDIgPC0gY29yX0FsbF9hbGx0aW1lICU+JSBkcGx5cjo6c2VsZWN0KGdyb3VwLCBhbGxfb2YoZ2dnZ19wbG90X2Nvcmxpc3RfdGltZSkpICU+JSBmaWx0ZXIoZ3JvdXAgJWluJSBnZ2dnX3Bsb3RfY29ybGlzdF90aW1lKSAlPiUgbXV0YXRlKGdyb3VwPWZhY3Rvcihncm91cCxnZ2dnX3Bsb3RfY29ybGlzdF90aW1lKSkgJT4lIGFycmFuZ2UoZ3JvdXApCm1hdF9jb3JfQWxsX2FsbHRpbWVfc2VsZWN0MiA8LSBjb3JfQWxsX2FsbHRpbWVfc2VsZWN0MiAlPiUgZHBseXI6OnNlbGVjdCgtZ3JvdXApICU+JSBhcy5tYXRyaXgoKQpyb3duYW1lcyhtYXRfY29yX0FsbF9hbGx0aW1lX3NlbGVjdDIpIDwtIGNvcl9BbGxfYWxsdGltZV9zZWxlY3QyJGdyb3VwCgoKY29yX0JSQmNsdXMzX2FsbHRpbWVfc2VsZWN0MiA8LSBjb3JfQlJCY2x1czNfYWxsdGltZSU+JSBkcGx5cjo6c2VsZWN0KGdyb3VwLCBhbGxfb2YoZ2dnZ19wbG90X2Nvcmxpc3RfdGltZSkpICU+JSBmaWx0ZXIoZ3JvdXAgJWluJSBnZ2dnX3Bsb3RfY29ybGlzdF90aW1lKSAlPiUgbXV0YXRlKGdyb3VwPWZhY3Rvcihncm91cCxnZ2dnX3Bsb3RfY29ybGlzdF90aW1lKSkgJT4lIGFycmFuZ2UoZ3JvdXApCm1hdF9jb3JfQlJCY2x1czNfYWxsdGltZV9zZWxlY3QyIDwtIGNvcl9CUkJjbHVzM19hbGx0aW1lX3NlbGVjdDIgJT4lIGRwbHlyOjpzZWxlY3QoLWdyb3VwKSAlPiUgYXMubWF0cml4KCkKcm93bmFtZXMobWF0X2Nvcl9CUkJjbHVzM19hbGx0aW1lX3NlbGVjdDIpIDwtIGNvcl9CUkJjbHVzM19hbGx0aW1lX3NlbGVjdDIkZ3JvdXAKCmdhcHNfMiA8LSBjKDgsMTYsMjQpCgojIyMjIHBsb3QgKHNlbGVjdCBvbmx5KQoKcGhlYXRtYXA6OnBoZWF0bWFwKG1hdF9jb3JfQlJCY2x1czNfYWxsdGltZV9zZWxlY3QyLCBtYWluID0gdGl0bGVfMSwgc2NhbGUgPSAibm9uZSIsIGNvbG9yID0gQ29sb3JfX2EsYnJlYWtzID0gYnJlYWtzTGlzdCwgYm9yZGVyX2NvbG9yPU5BLCBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgY2x1c3Rlcl9jb2xzID0gRkFMU0UsIGdhcHNfY29sPWdhcHNfMiwgZ2Fwc19yb3c9Z2Fwc18yKQpwaGVhdG1hcDo6cGhlYXRtYXAobWF0X2Nvcl9BbGxfYWxsdGltZV9zZWxlY3QyLCBtYWluID0gdGl0bGVfMiwgc2NhbGUgPSAibm9uZSIsIGNvbG9yID0gQ29sb3JfX2EsYnJlYWtzID0gYnJlYWtzTGlzdCwgYm9yZGVyX2NvbG9yPU5BLCBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgY2x1c3Rlcl9jb2xzID0gRkFMU0UsIGdhcHNfY29sPWdhcHNfMiwgZ2Fwc19yb3c9Z2Fwc18yKQoKCgpgYGAgIAogIAogIAoKYGBge3Igbm9ybSBjb3JycGxvdCBub3JtIHR5cGVtZWFuIGFsbCwgZmlnLndpZHRoPTQsZmlnLmhlaWdodD00fQoKbXlkYXRhLmNvci5CUkJjbHVzMy5VSSA8LSBjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czNCUkJjbHVzM19maWx0ZXIgJT4lIHVuZ3JvdXAoKSAlPiUgZmlsdGVyKHRpbWU9PSJVSSIpICU+JSBkcGx5cjo6c2VsZWN0KEJSQl9Eb3hNaW51cywgQlJCX0RveFBsdXMsIEgzcDNfRG94TWludXMsSDNwM19Eb3hQbHVzLEgzSzRtZTNfRG94TWludXMsSDNLNG1lM19Eb3hQbHVzLEgzSzI3YWNfRG94TWludXMsSDNLMjdhY19Eb3hQbHVzKSAlPiUgY29yKG1ldGhvZCA9IGMoInNwZWFybWFuIikpCm15ZGF0YS5jb3IuQlJCY2x1czMuMGggPC0gY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzQlJCY2x1czNfZmlsdGVyICU+JSB1bmdyb3VwKCkgJT4lIGZpbHRlcih0aW1lPT0iMGgiKSAgICU+JSBkcGx5cjo6c2VsZWN0KEJSQl9Eb3hNaW51cywgQlJCX0RveFBsdXMsIEgzcDNfRG94TWludXMsSDNwM19Eb3hQbHVzLEgzSzRtZTNfRG94TWludXMsSDNLNG1lM19Eb3hQbHVzLEgzSzI3YWNfRG94TWludXMsSDNLMjdhY19Eb3hQbHVzKSAlPiUgY29yKG1ldGhvZCA9IGMoInNwZWFybWFuIikpCm15ZGF0YS5jb3IuQlJCY2x1czMuMjRoIDwtIGNvcnJfdHlwZW1lYW5fY3V0b2ZmX0gzcDNjbHVzM0JSQmNsdXMzX2ZpbHRlciAlPiUgdW5ncm91cCgpICU+JSBmaWx0ZXIodGltZT09IjI0aCIpICAlPiUgZHBseXI6OnNlbGVjdChCUkJfRG94TWludXMsIEJSQl9Eb3hQbHVzLCBIM3AzX0RveE1pbnVzLEgzcDNfRG94UGx1cyxIM0s0bWUzX0RveE1pbnVzLEgzSzRtZTNfRG94UGx1cyxIM0syN2FjX0RveE1pbnVzLEgzSzI3YWNfRG94UGx1cykgJT4lIGNvcihtZXRob2QgPSBjKCJzcGVhcm1hbiIpKQpteWRhdGEuY29yLkJSQmNsdXMzLjQ4aCA8LSBjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czNCUkJjbHVzM19maWx0ZXIgJT4lIHVuZ3JvdXAoKSAgJT4lIGZpbHRlcih0aW1lPT0iNDhoIikgICU+JSBkcGx5cjo6c2VsZWN0KEJSQl9Eb3hNaW51cywgQlJCX0RveFBsdXMsIEgzcDNfRG94TWludXMsSDNwM19Eb3hQbHVzLEgzSzRtZTNfRG94TWludXMsSDNLNG1lM19Eb3hQbHVzLEgzSzI3YWNfRG94TWludXMsSDNLMjdhY19Eb3hQbHVzKSAlPiUgY29yKG1ldGhvZCA9IGMoInNwZWFybWFuIikpCgpteWRhdGEuY29yLkFsbC5VSSA8LSBjb3JyX3R5cGVtZWFuX2N1dG9mZl9IM3AzY2x1czNfZmlsdGVyICU+JSB1bmdyb3VwKCkgJT4lIGZpbHRlcih0aW1lPT0iVUkiKSAgJT4lIGRwbHlyOjpzZWxlY3QoQlJCX0RveE1pbnVzLCBCUkJfRG94UGx1cywgSDNwM19Eb3hNaW51cyxIM3AzX0RveFBsdXMsSDNLNG1lM19Eb3hNaW51cyxIM0s0bWUzX0RveFBsdXMsSDNLMjdhY19Eb3hNaW51cyxIM0syN2FjX0RveFBsdXMpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKbXlkYXRhLmNvci5BbGwuMGggPC0gY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzX2ZpbHRlciAlPiUgdW5ncm91cCgpICU+JSBmaWx0ZXIodGltZT09IjBoIikgICAlPiUgZHBseXI6OnNlbGVjdChCUkJfRG94TWludXMsIEJSQl9Eb3hQbHVzLCBIM3AzX0RveE1pbnVzLEgzcDNfRG94UGx1cyxIM0s0bWUzX0RveE1pbnVzLEgzSzRtZTNfRG94UGx1cyxIM0syN2FjX0RveE1pbnVzLEgzSzI3YWNfRG94UGx1cykgJT4lIGNvcihtZXRob2QgPSBjKCJzcGVhcm1hbiIpKQpteWRhdGEuY29yLkFsbC4yNGggPC0gY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzX2ZpbHRlciAlPiUgdW5ncm91cCgpICU+JSBmaWx0ZXIodGltZT09IjI0aCIpICAlPiUgZHBseXI6OnNlbGVjdChCUkJfRG94TWludXMsIEJSQl9Eb3hQbHVzLCBIM3AzX0RveE1pbnVzLEgzcDNfRG94UGx1cyxIM0s0bWUzX0RveE1pbnVzLEgzSzRtZTNfRG94UGx1cyxIM0syN2FjX0RveE1pbnVzLEgzSzI3YWNfRG94UGx1cykgJT4lIGNvcihtZXRob2QgPSBjKCJzcGVhcm1hbiIpKQpteWRhdGEuY29yLkFsbC40OGggPC0gY29ycl90eXBlbWVhbl9jdXRvZmZfSDNwM2NsdXMzX2ZpbHRlciAlPiUgdW5ncm91cCgpICAlPiUgZmlsdGVyKHRpbWU9PSI0OGgiKSAlPiUgZHBseXI6OnNlbGVjdChCUkJfRG94TWludXMsIEJSQl9Eb3hQbHVzLCBIM3AzX0RveE1pbnVzLEgzcDNfRG94UGx1cyxIM0s0bWUzX0RveE1pbnVzLEgzSzRtZTNfRG94UGx1cyxIM0syN2FjX0RveE1pbnVzLEgzSzI3YWNfRG94UGx1cykgJT4lIGNvcihtZXRob2QgPSBjKCJzcGVhcm1hbiIpKQoKCiNjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLlVJLCBkaWFnID0gRkFMU0UsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQojY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy4waCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuMjRoLCBkaWFnID0gRkFMU0UsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQojY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy40OGgsIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCgojY29ycnBsb3QobXlkYXRhLmNvci5BbGwuVUksIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCiNjb3JycGxvdChteWRhdGEuY29yLkFsbC4waCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLjI0aCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLjQ4aCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKCmNvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuVUksIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIikKY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy4waCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiKQpjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjI0aCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiKQpjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjQ4aCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiKQoKY29ycnBsb3QobXlkYXRhLmNvci5BbGwuVUksIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIikKY29ycnBsb3QobXlkYXRhLmNvci5BbGwuMGgsIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIikKY29ycnBsb3QobXlkYXRhLmNvci5BbGwuMjRoLCBkaWFnID0gRkFMU0UsIG1ldGhvZCA9ICJjb2xvciIpCmNvcnJwbG90KG15ZGF0YS5jb3IuQWxsLjQ4aCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiKQoKY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy5VSSwgZGlhZyA9IEZBTFNFKQpjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjBoLCBkaWFnID0gRkFMU0UpCmNvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuMjRoLCBkaWFnID0gRkFMU0UpCmNvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuNDhoLCBkaWFnID0gRkFMU0UpCgpjb3JycGxvdChteWRhdGEuY29yLkFsbC5VSSwgZGlhZyA9IEZBTFNFKQpjb3JycGxvdChteWRhdGEuY29yLkFsbC4waCwgZGlhZyA9IEZBTFNFKQpjb3JycGxvdChteWRhdGEuY29yLkFsbC4yNGgsIGRpYWcgPSBGQUxTRSkKY29ycnBsb3QobXlkYXRhLmNvci5BbGwuNDhoLCBkaWFnID0gRkFMU0UpCgojY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy5VSSwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSBjbS5jb2xvcnMoMTAwKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuMGgsIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gY20uY29sb3JzKDEwMCkpCiNjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjI0aCwgZGlhZyA9IEZBTFNFLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSBjbS5jb2xvcnMoMTAwKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuNDhoLCBkaWFnID0gRkFMU0UsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IGNtLmNvbG9ycygxMDApKQoKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLlVJLCBkaWFnID0gRkFMU0UsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IGNtLmNvbG9ycygxMDApKQojY29ycnBsb3QobXlkYXRhLmNvci5BbGwuMGgsIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gY20uY29sb3JzKDEwMCkpCiNjb3JycGxvdChteWRhdGEuY29yLkFsbC4yNGgsIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gY20uY29sb3JzKDEwMCkpCiNjb3JycGxvdChteWRhdGEuY29yLkFsbC40OGgsIGRpYWcgPSBGQUxTRSwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gY20uY29sb3JzKDEwMCkpCgojY29ycnBsb3QubWl4ZWQoY29yKG15ZGF0YS5jb3IpLCBvcmRlcj0iaGNsdXN0IiwgdGwuY29sPSJibGFjayIpCgoKI3BoZWF0bWFwOjpwaGVhdG1hcChteWRhdGEuY29yLkFsbC5VSSxjb2xvcj12aXJpZGlzOjp2aXJpZGlzKDI1Niksc2NhbGUgPSAibm9uZSIpCiNwaGVhdG1hcDo6cGhlYXRtYXAobXlkYXRhLmNvci5BbGwuMGgsY29sb3I9dmlyaWRpczo6dmlyaWRpcygyNTYpLHNjYWxlID0gIm5vbmUiKQojcGhlYXRtYXA6OnBoZWF0bWFwKG15ZGF0YS5jb3IuQWxsLjI0aCxjb2xvcj12aXJpZGlzOjp2aXJpZGlzKDI1Niksc2NhbGUgPSAibm9uZSIpCiNwaGVhdG1hcDo6cGhlYXRtYXAobXlkYXRhLmNvci5BbGwuNDhoLGNvbG9yPXZpcmlkaXM6OnZpcmlkaXMoMjU2KSxzY2FsZSA9ICJub25lIikKCiNwaGVhdG1hcDo6cGhlYXRtYXAobXlkYXRhLmNvci5CUkJjbHVzMy5VSSxjb2xvcj12aXJpZGlzOjp2aXJpZGlzKDI1Niksc2NhbGUgPSAibm9uZSIpCiNwaGVhdG1hcDo6cGhlYXRtYXAobXlkYXRhLmNvci5CUkJjbHVzMy4waCxjb2xvcj12aXJpZGlzOjp2aXJpZGlzKDI1Niksc2NhbGUgPSAibm9uZSIpCiNwaGVhdG1hcDo6cGhlYXRtYXAobXlkYXRhLmNvci5CUkJjbHVzMy4yNGgsY29sb3I9dmlyaWRpczo6dmlyaWRpcygyNTYpLHNjYWxlID0gIm5vbmUiKQojcGhlYXRtYXA6OnBoZWF0bWFwKG15ZGF0YS5jb3IuQlJCY2x1czMuNDhoLGNvbG9yPXZpcmlkaXM6OnZpcmlkaXMoMjU2KSxzY2FsZSA9ICJub25lIikKCiNjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLlVJLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAidXBwZXIiLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuMGgsIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJ1cHBlciIsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQojY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy4yNGgsIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJ1cHBlciIsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQojY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy40OGgsIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJ1cHBlciIsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQoKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLlVJLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAibG93ZXIiLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLjBoLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAibG93ZXIiLCBtZXRob2QgPSAiY29sb3IiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLjI0aCwgZGlhZyA9IEZBTFNFLCB0eXBlID0gImxvd2VyIiwgbWV0aG9kID0gImNvbG9yIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCiNjb3JycGxvdChteWRhdGEuY29yLkFsbC40OGgsIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJsb3dlciIsIG1ldGhvZCA9ICJjb2xvciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQoKCiNjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLlVJLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAidXBwZXIiLCBtZXRob2QgPSAic3F1YXJlIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCiNjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjBoLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAidXBwZXIiLCBtZXRob2QgPSAic3F1YXJlIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCiNjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjI0aCwgZGlhZyA9IEZBTFNFLCB0eXBlID0gInVwcGVyIiwgbWV0aG9kID0gInNxdWFyZSIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQojY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy40OGgsIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJ1cHBlciIsIG1ldGhvZCA9ICJzcXVhcmUiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKCiNjb3JycGxvdChteWRhdGEuY29yLkFsbC5VSSwgZGlhZyA9IEZBTFNFLCB0eXBlID0gImxvd2VyIiwgbWV0aG9kID0gInNxdWFyZSIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQojY29ycnBsb3QobXlkYXRhLmNvci5BbGwuMGgsIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJsb3dlciIsIG1ldGhvZCA9ICJzcXVhcmUiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKI2NvcnJwbG90KG15ZGF0YS5jb3IuQWxsLjI0aCwgZGlhZyA9IEZBTFNFLCB0eXBlID0gImxvd2VyIiwgbWV0aG9kID0gInNxdWFyZSIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQojY29ycnBsb3QobXlkYXRhLmNvci5BbGwuNDhoLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAibG93ZXIiLCBtZXRob2QgPSAic3F1YXJlIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCgojY29ycnBsb3QubWl4ZWQobXlkYXRhLmNvci5CUkJjbHVzMy5VSSwgbG93ZXIuY29sID0gImJsYWNrIikKI2NvcnJwbG90Lm1peGVkKG15ZGF0YS5jb3IuQlJCY2x1czMuMGgsIGxvd2VyLmNvbCA9ICJibGFjayIpCiNjb3JycGxvdC5taXhlZChteWRhdGEuY29yLkJSQmNsdXMzLjI0aCwgbG93ZXIuY29sID0gImJsYWNrIikKI2NvcnJwbG90Lm1peGVkKG15ZGF0YS5jb3IuQlJCY2x1czMuNDhoLCBsb3dlci5jb2wgPSAiYmxhY2siKQoKI2NvcnJwbG90KG15ZGF0YS5jb3IscGFsZXR0ZSA9ICJQdU9yIikKCmBgYAoKCgpgYGB7ciBrb2tva30KCmxpYnJhcnkoY29ycnBsb3QpCiMgPSByZWFkLmNzdigiaHR0cHM6Ly93aWtpLnEtcmVzZWFyY2hzb2Z0d2FyZS5jb20vaW1hZ2VzL2IvYjkvT3duZXJzaGlwLmNzdiIsIGhlYWRlciA9IFRSVUUsIGZpbGVFbmNvZGluZz0ibGF0aW4xIikKI215ZGF0YS5jb3IgPSBjb3IobXlkYXRhKQojbXlkYXRhLmNvciA9IGNvcihteWRhdGEsIG1ldGhvZCA9IGMoInNwZWFybWFuIikKI2NvcnJwbG90KG15ZGF0YS5jb3IpCgojbXlkYXRhLmNvci5VSSA8LSByYW5rX2NvcnJfSDNwM2NsdXMzQlJCY2x1czMgJT4lIGZpbHRlcih0aW1lPT0iVUkiKSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSxleHRfZ2VuZSx0aW1lLEgzcDMsSDNLNG1lMyxIM0syN2FjLEJSQikgJT4lIHRpZHlyOjpnYXRoZXIoa2V5PSJzZXEiLHZhbHVlPUZDLC1lbnNfZ2VuZSwtZXh0X2dlbmUsLXRpbWUpICU+JSBtdXRhdGUodGltZV9zZXE9cGFzdGUodGltZSxzZXEsc2VwPSJfIikpICU+JSB1bmdyb3VwICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLHRpbWVfc2VxLEZDKSAlPiUgdGlkeXI6OnNwcmVhZChrZXkgPSB0aW1lX3NlcSx2YWx1ZT1GQykgJT4lIGRwbHlyOjpzZWxlY3QoLWVuc19nZW5lKSAlPiUgY29yKG1ldGhvZCA9IGMoInNwZWFybWFuIikpCgojbXlkYXRhLmNvci4waCA8LSByYW5rX2NvcnJfSDNwM2NsdXMzQlJCY2x1czMgJT4lIGZpbHRlcih0aW1lPT0iMGgiKSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSxleHRfZ2VuZSx0aW1lLEgzcDMsSDNLNG1lMyxIM0syN2FjLEJSQikgJT4lIHRpZHlyOjpnYXRoZXIoa2V5PSJzZXEiLHZhbHVlPUZDLC1lbnNfZ2VuZSwtZXh0X2dlbmUsLXRpbWUpICU+JSBtdXRhdGUodGltZV9zZXE9cGFzdGUodGltZSxzZXEsc2VwPSJfIikpICU+JSB1bmdyb3VwICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLHRpbWVfc2VxLEZDKSAlPiUgdGlkeXI6OnNwcmVhZChrZXkgPSB0aW1lX3NlcSx2YWx1ZT1GQykgJT4lIGRwbHlyOjpzZWxlY3QoLWVuc19nZW5lKSAlPiUgY29yKG1ldGhvZCA9IGMoInNwZWFybWFuIikpCgojbXlkYXRhLmNvci4yNGggPC0gcmFua19jb3JyX0gzcDNjbHVzM0JSQmNsdXMzICU+JSBmaWx0ZXIodGltZT09IjI0aCIpICU+JSBkcGx5cjo6c2VsZWN0KGVuc19nZW5lLGV4dF9nZW5lLHRpbWUsSDNwMyxIM0s0bWUzLEgzSzI3YWMsQlJCKSAlPiUgdGlkeXI6OmdhdGhlcihrZXk9InNlcSIsdmFsdWU9RkMsLWVuc19nZW5lLC1leHRfZ2VuZSwtdGltZSkgJT4lIG11dGF0ZSh0aW1lX3NlcT1wYXN0ZSh0aW1lLHNlcSxzZXA9Il8iKSkgJT4lIHVuZ3JvdXAgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsdGltZV9zZXEsRkMpICU+JSB0aWR5cjo6c3ByZWFkKGtleSA9IHRpbWVfc2VxLHZhbHVlPUZDKSAlPiUgZHBseXI6OnNlbGVjdCgtZW5zX2dlbmUpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKCiNteWRhdGEuY29yLjQ4aCA8LSByYW5rX2NvcnJfSDNwM2NsdXMzQlJCY2x1czMgJT4lIGZpbHRlcih0aW1lPT0iNDhoIikgJT4lIGRwbHlyOjpzZWxlY3QoZW5zX2dlbmUsZXh0X2dlbmUsdGltZSxIM3AzLEgzSzRtZTMsSDNLMjdhYyxCUkIpICU+JSB0aWR5cjo6Z2F0aGVyKGtleT0ic2VxIix2YWx1ZT1GQywtZW5zX2dlbmUsLWV4dF9nZW5lLC10aW1lKSAlPiUgbXV0YXRlKHRpbWVfc2VxPXBhc3RlKHRpbWUsc2VxLHNlcD0iXyIpKSAlPiUgdW5ncm91cCAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSx0aW1lX3NlcSxGQykgJT4lIHRpZHlyOjpzcHJlYWQoa2V5ID0gdGltZV9zZXEsdmFsdWU9RkMpICU+JSBkcGx5cjo6c2VsZWN0KC1lbnNfZ2VuZSkgJT4lIGNvcihtZXRob2QgPSBjKCJzcGVhcm1hbiIpKQoKbXlkYXRhLmNvci5CUkJjbHVzMy5VSSA8LSByYW5rX2NvcnJfSDNwM2NsdXMzQlJCY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZmlsdGVyKHRpbWU9PSJVSSIpICU+JSBkcGx5cjo6c2VsZWN0KEJSQiwgSDNwMyxIM0s0bWUzLEgzSzI3YWMpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKbXlkYXRhLmNvci5CUkJjbHVzMy4waCA8LSByYW5rX2NvcnJfSDNwM2NsdXMzQlJCY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZmlsdGVyKHRpbWU9PSIwaCIpICAlPiUgZHBseXI6OnNlbGVjdChCUkIsIEgzcDMsSDNLNG1lMyxIM0syN2FjKSAlPiUgY29yKG1ldGhvZCA9IGMoInNwZWFybWFuIikpCm15ZGF0YS5jb3IuQlJCY2x1czMuMjRoIDwtIHJhbmtfY29ycl9IM3AzY2x1czNCUkJjbHVzMyAlPiUgdW5ncm91cCgpICU+JSBmaWx0ZXIodGltZT09IjI0aCIpICU+JSBkcGx5cjo6c2VsZWN0KEJSQiwgSDNwMyxIM0s0bWUzLEgzSzI3YWMpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKbXlkYXRhLmNvci5CUkJjbHVzMy40OGggPC0gcmFua19jb3JyX0gzcDNjbHVzM0JSQmNsdXMzICU+JSB1bmdyb3VwKCkgICU+JSBmaWx0ZXIodGltZT09IjQ4aCIpICU+JSBkcGx5cjo6c2VsZWN0KEJSQiwgSDNwMyxIM0s0bWUzLEgzSzI3YWMpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKCm15ZGF0YS5jb3IuQWxsLlVJIDwtIHJhbmtfY29ycl9IM3AzY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZmlsdGVyKHRpbWU9PSJVSSIpICU+JSBkcGx5cjo6c2VsZWN0KEJSQiwgSDNwMyxIM0s0bWUzLEgzSzI3YWMpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKbXlkYXRhLmNvci5BbGwuMGggPC0gcmFua19jb3JyX0gzcDNjbHVzMyAlPiUgdW5ncm91cCgpICU+JSBmaWx0ZXIodGltZT09IjBoIikgICU+JSBkcGx5cjo6c2VsZWN0KEJSQiwgSDNwMyxIM0s0bWUzLEgzSzI3YWMpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKbXlkYXRhLmNvci5BbGwuMjRoIDwtIHJhbmtfY29ycl9IM3AzY2x1czMgJT4lIHVuZ3JvdXAoKSAlPiUgZmlsdGVyKHRpbWU9PSIyNGgiKSAlPiUgZHBseXI6OnNlbGVjdChCUkIsIEgzcDMsSDNLNG1lMyxIM0syN2FjKSAlPiUgY29yKG1ldGhvZCA9IGMoInNwZWFybWFuIikpCm15ZGF0YS5jb3IuQWxsLjQ4aCA8LSByYW5rX2NvcnJfSDNwM2NsdXMzICU+JSB1bmdyb3VwKCkgICU+JSBmaWx0ZXIodGltZT09IjQ4aCIpICU+JSBkcGx5cjo6c2VsZWN0KEJSQiwgSDNwMyxIM0s0bWUzLEgzSzI3YWMpICU+JSBjb3IobWV0aG9kID0gYygic3BlYXJtYW4iKSkKCgojY29ycnBsb3QubWl4ZWQoY29yKG15ZGF0YS5jb3IpLCBvcmRlcj0iaGNsdXN0IiwgdGwuY29sPSJibGFjayIpCmNvcnJwbG90KG15ZGF0YS5jb3IuQlJCY2x1czMuVUksIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJ1cHBlciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQpjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjBoLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAidXBwZXIiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKY29ycnBsb3QobXlkYXRhLmNvci5CUkJjbHVzMy4yNGgsIGRpYWcgPSBGQUxTRSwgdHlwZSA9ICJ1cHBlciIsIGNvbCA9IHJldihicmV3ZXIucGFsKG4gPSAxMCwgbmFtZSA9ICJSZEJ1IikpKQpjb3JycGxvdChteWRhdGEuY29yLkJSQmNsdXMzLjQ4aCwgZGlhZyA9IEZBTFNFLCB0eXBlID0gInVwcGVyIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCgpjb3JycGxvdChteWRhdGEuY29yLkFsbC5VSSwgZGlhZyA9IEZBTFNFLCB0eXBlID0gImxvd2VyIiwgY29sID0gcmV2KGJyZXdlci5wYWwobiA9IDEwLCBuYW1lID0gIlJkQnUiKSkpCmNvcnJwbG90KG15ZGF0YS5jb3IuQWxsLjBoLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAibG93ZXIiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKY29ycnBsb3QobXlkYXRhLmNvci5BbGwuMjRoLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAibG93ZXIiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKY29ycnBsb3QobXlkYXRhLmNvci5BbGwuNDhoLCBkaWFnID0gRkFMU0UsIHR5cGUgPSAibG93ZXIiLCBjb2wgPSByZXYoYnJld2VyLnBhbChuID0gMTAsIG5hbWUgPSAiUmRCdSIpKSkKCiNjb3JycGxvdC5taXhlZChteWRhdGEuY29yLkJSQmNsdXMzLlVJLCBsb3dlci5jb2wgPSAiYmxhY2siKQojY29ycnBsb3QubWl4ZWQobXlkYXRhLmNvci5CUkJjbHVzMy4waCwgbG93ZXIuY29sID0gImJsYWNrIikKI2NvcnJwbG90Lm1peGVkKG15ZGF0YS5jb3IuQlJCY2x1czMuMjRoLCBsb3dlci5jb2wgPSAiYmxhY2siKQojY29ycnBsb3QubWl4ZWQobXlkYXRhLmNvci5CUkJjbHVzMy40OGgsIGxvd2VyLmNvbCA9ICJibGFjayIpCgojY29ycnBsb3QobXlkYXRhLmNvcixwYWxldHRlID0gIlB1T3IiKQoKYGBgCgoKc3BlYXJtYW7jgahyYW5raW5nPT5wZWFzb24g44Gu55u46Zai5L+C5pWw44GM5ZCI44Gj44Gm44GE44KL44GL44KS6Kq/44G544KL44GT44GoCgoKYGBge3IgcGxvdCBsb2cyRkMgc3VtbWFyeSBjb3JydGVzdH0KCiMlPiUgZ3JvdXBfYnkodGFyZ2V0LHRpbWUsQ29tcGFyZSkKIyAgZ3JvdXBfYnkoYXNwZWN0LGdzX2NhdCxnc19zdWJjYXQpICU+JQojICBtdXRhdGUocGFkaj1wLmFkanVzdChwdmFsLCJCSCIpKSAlPiUgdW5ncm91cCgpCiNDb3J0ZXN0X0gzcDNjbHVzM0FsbCA8LSByZWFkcjo6cmVhZF9jc3YoIi4vbG9nMkZDL3RhYmxlcy9Db3J0ZXN0X3Jlc3VsdF9zcGVhcm1hbl9IM3AzY2x1czNBbGwuY3N2IikgJT4lIG11dGF0ZSh0ZXh0PXBhc3RlKCIgQWxsICgiLFBsb3RfZ2VuZXMsIikgQ29yOiAiLHNwcmludGYoIiU0LjNlIiwgZXN0aW1hdGUuY29yKSwiLCBwLnZhbDogIixzcHJpbnRmKCIlNC4zZSIsIHAudmFsdWUpLHNlcD0iIikpICAgJT4lIG11dGF0ZSh0aW1lPWZhY3Rvcih0aW1lLCBjKCJVSSIsICIwaCIsIjI0aCIsIjQ4aCIpKSkgJT4lIGFycmFuZ2UodGltZSkKI0NvcnRlc3RfSDNwM2NsdXMzQlJCY2x1czMgPC0gcmVhZHI6OnJlYWRfY3N2KCIuL2xvZzJGQy90YWJsZXMvQ29ydGVzdF9yZXN1bHRfc3BlYXJtYW5fSDNwM2NsdXMzQlJCY2x1czMuY3N2IikgICU+JSBtdXRhdGUodGV4dD1wYXN0ZSgiQ2x1czMgKCIsUGxvdF9nZW5lcywiKSBDb3I6ICIsc3ByaW50ZigiJTQuM2UiLCBlc3RpbWF0ZS5jb3IpLCIsIHAudmFsOiAiLHNwcmludGYoIiU0LjNlIiwgcC52YWx1ZSksc2VwPSIiKSkgICU+JSBtdXRhdGUodGltZT1mYWN0b3IodGltZSwgYygiVUkiLCAiMGgiLCIyNGgiLCI0OGgiKSkpICU+JSBhcnJhbmdlKHRpbWUpCgoKQ29ydGVzdF9IM3AzY2x1czNBbGwgPC0gcmVhZHI6OnJlYWRfY3N2KCIuL2xvZzJGQy90YWJsZXMvQ29ydGVzdF9yZXN1bHRfc3BlYXJtYW5fSDNwM2NsdXMzQWxsLmNzdiIpICU+JSBtdXRhdGUodGV4dD1wYXN0ZSgiIEFsbCAoIixQbG90X2dlbmVzLCIpIFNwZWFybWFuIENvcjogIixzcHJpbnRmKCIlNC4zZSIsIGVzdGltYXRlLnJobyksIiwgcC52YWw6ICIsc3ByaW50ZigiJTQuM2UiLCBwLnZhbHVlKSxzZXA9IiIpKSAgICU+JSBtdXRhdGUodGltZT1mYWN0b3IodGltZSwgYygiVUkiLCAiMGgiLCIyNGgiLCI0OGgiKSkpICU+JSBhcnJhbmdlKHRpbWUpCkNvcnRlc3RfSDNwM2NsdXMzQlJCY2x1czMgPC0gcmVhZHI6OnJlYWRfY3N2KCIuL2xvZzJGQy90YWJsZXMvQ29ydGVzdF9yZXN1bHRzX3NwZWFybWFuX0gzcDNjbHVzM0JSQmNsdXMzLmNzdiIpICAlPiUgbXV0YXRlKHRleHQ9cGFzdGUoIkNsdXMzICgiLFBsb3RfZ2VuZXMsIikgU3BlYXJtYW4gQ29yOiAiLHNwcmludGYoIiU0LjNlIiwgZXN0aW1hdGUucmhvKSwiLCBwLnZhbDogIixzcHJpbnRmKCIlNC4zZSIsIHAudmFsdWUpLHNlcD0iIikpICAlPiUgbXV0YXRlKHRpbWU9ZmFjdG9yKHRpbWUsIGMoIlVJIiwgIjBoIiwiMjRoIiwiNDhoIikpKSAlPiUgYXJyYW5nZSh0aW1lKQoKQ29ydGVzdF9IM3AzY2x1czNBbGwgJT4lIHJlYWRyOjp3cml0ZV9jc3YoIi4vbG9nMkZDL3RhYmxlcy9Db3J0ZXN0X3Jlc3VsdF9zcGVhcm1hbl9IM3AzY2x1czNBbGxfZm9yUGxvdC5jc3YiKQpDb3J0ZXN0X0gzcDNjbHVzM0JSQmNsdXMzICU+JSByZWFkcjo6d3JpdGVfY3N2KCIuL2xvZzJGQy90YWJsZXMvQ29ydGVzdF9yZXN1bHRfc3BlYXJtYW5fSDNwM2NsdXMzQlJCY2x1czNfZm9yUGxvdC5jc3YiKQpgYGAKCgoKYGBge3Igbm90IHNob3duIGxvZzJGQ30KClNob3dwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzIDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIG11dGF0ZShIM3AzdnNCUkI9Y2FzZV93aGVuKCgoYWJzKEJSQik+Mil8KGFicyhIM3AzKT4xLjApfGlzLm5hKEgzcDMpKX4iTm90IFNob3duIixUUlVFfiJTaG93biIpLEgzSzRtZTN2c0JSQj1jYXNlX3doZW4oKChhYnMoQlJCKT4yKXwoYWJzKEgzSzRtZTMpPjEuNSl8aXMubmEoSDNLNG1lMykpfiJOb3QgU2hvd24iLFRSVUV+IlNob3duIiksSDNLMjdhY3ZzQlJCPWNhc2Vfd2hlbigoKGFicyhCUkIpPjIpfChhYnMoSDNLMjdhYyk+MS4wKXxpcy5uYShIM0syN2FjKSl+Ik5vdCBTaG93biIsVFJVRX4iU2hvd24iKSxIM0syN21lM3ZzQlJCPWNhc2Vfd2hlbigoKGFicyhCUkIpPjIpfChhYnMoSDNLMjdtZTMpPjEuMCl8aXMubmEoSDNLMjdtZTMpKX4iTm90IFNob3duIixUUlVFfiJTaG93biIpLEFUQUN2c0JSQj1jYXNlX3doZW4oKChhYnMoQlJCKT4yKXwoYWJzKEFUQUMpPjAuNCl8aXMubmEoQVRBQykpfiJOb3QgU2hvd24iLFRSVUV+IlNob3duIikpCgpTaG93X0gzcDN2c0JSQl9IM3AzY2x1czNBbGwgPC0gU2hvd3Bsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIHVuZ3JvdXAgJT4lIGdyb3VwX2J5KEgzcDN2c0JSQix0aW1lKSAlPiUgc3VtbWFyaXplKGNvdW50PW4oKSkgJT4lIHJlbmFtZShQbG90PUgzcDN2c0JSQikgJT4lIG11dGF0ZShDb21wYXJlPSJIM3AzX0JSQiIpClNob3dfSDNLNG1lM3ZzQlJCX0gzcDNjbHVzM0FsbCA8LSBTaG93cGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoSDNLNG1lM3ZzQlJCLHRpbWUpICU+JSBzdW1tYXJpemUoY291bnQ9bigpKSAlPiUgcmVuYW1lKFBsb3Q9SDNLNG1lM3ZzQlJCKSAlPiUgbXV0YXRlKENvbXBhcmU9IkgzSzRtZTNfQlJCIikKU2hvd19IM0syN2FjdnNCUkJfSDNwM2NsdXMzQWxsIDwtIFNob3dwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShIM0syN2FjdnNCUkIsdGltZSkgJT4lIHN1bW1hcml6ZShjb3VudD1uKCkpICU+JSByZW5hbWUoUGxvdD1IM0syN2FjdnNCUkIpICU+JSBtdXRhdGUoQ29tcGFyZT0iSDNLMjdhY19CUkIiKQpTaG93X0gzSzI3bWUzdnNCUkJfSDNwM2NsdXMzQWxsIDwtIFNob3dwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShIM0syN21lM3ZzQlJCLHRpbWUpICU+JSBzdW1tYXJpemUoY291bnQ9bigpKSAlPiUgcmVuYW1lKFBsb3Q9SDNLMjdtZTN2c0JSQiklPiUgbXV0YXRlKENvbXBhcmU9IkgzSzI3bWUzX0JSQiIpClNob3dfQVRBQ3ZzQlJCX0gzcDNjbHVzM0FsbCA8LSBTaG93cGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoQVRBQ3ZzQlJCLHRpbWUpICU+JSBzdW1tYXJpemUoY291bnQ9bigpKSAlPiUgcmVuYW1lKFBsb3Q9QVRBQ3ZzQlJCKSU+JSBtdXRhdGUoQ29tcGFyZT0iQVRBQ19CUkIiKQoKClNob3dfX3ZzQlJCX0gzcDNjbHVzM0FsbCA8LSBiaW5kX3Jvd3MoU2hvd19IM3AzdnNCUkJfSDNwM2NsdXMzQWxsLFNob3dfSDNLNG1lM3ZzQlJCX0gzcDNjbHVzM0FsbCkgJT4lIGJpbmRfcm93cyhTaG93X0gzSzI3YWN2c0JSQl9IM3AzY2x1czNBbGwpICU+JSBiaW5kX3Jvd3MoU2hvd19IM0syN21lM3ZzQlJCX0gzcDNjbHVzM0FsbCkgJT4lIGJpbmRfcm93cyhTaG93X0FUQUN2c0JSQl9IM3AzY2x1czNBbGwpICU+JSBtdXRhdGUodGFyZ2V0PSJIM3AzY2x1czNBbGwiKSAgJT4lIG11dGF0ZShDb3VudD1jYXNlX3doZW4oUGxvdD09Ik5vdCBTaG93biJ+cGFzdGUoIigiLGNvdW50LCIpIixzZXA9IiIpLFRSVUV+YXMuY2hhcmFjdGVyKGNvdW50KSkpICU+JSBtdXRhdGUoUGxvdD1mYWN0b3IoUGxvdCwgYygiU2hvd24iLCJOb3QgU2hvd24iKSkpICU+JSBhcnJhbmdlKENvbXBhcmUsdGltZSxQbG90KQoKClNob3dfSDNwM3ZzQlJCX0gzcDNjbHVzM0JSQmNsdXMzIDwtIFNob3dwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBmaWx0ZXIoQlJCREVHY2x1c3Rlcj09IjMiKSAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoSDNwM3ZzQlJCLHRpbWUpICU+JSBzdW1tYXJpemUoY291bnQ9bigpLGdlbmU9cGFzdGUoZXh0X2dlbmUsY29sbGFwc2UgPSAiLCIpKSAlPiUgcmVuYW1lKFBsb3Q9SDNwM3ZzQlJCKSAlPiUgbXV0YXRlKENvbXBhcmU9IkgzcDNfQlJCIikKU2hvd19IM0s0bWUzdnNCUkJfSDNwM2NsdXMzQlJCY2x1czMgPC0gU2hvd3Bsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZpbHRlcihCUkJERUdjbHVzdGVyPT0iMyIpJT4lIHVuZ3JvdXAgJT4lIGdyb3VwX2J5KEgzSzRtZTN2c0JSQix0aW1lKSAlPiUgc3VtbWFyaXplKGNvdW50PW4oKSxnZW5lPXBhc3RlKGV4dF9nZW5lLGNvbGxhcHNlID0gIiwiKSkgJT4lIHJlbmFtZShQbG90PUgzSzRtZTN2c0JSQikgJT4lIG11dGF0ZShDb21wYXJlPSJIM0s0bWUzX0JSQiIpClNob3dfSDNLMjdhY3ZzQlJCX0gzcDNjbHVzM0JSQmNsdXMzIDwtIFNob3dwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBmaWx0ZXIoQlJCREVHY2x1c3Rlcj09IjMiKSU+JSB1bmdyb3VwICU+JSBncm91cF9ieShIM0syN2FjdnNCUkIsdGltZSkgJT4lIHN1bW1hcml6ZShjb3VudD1uKCksZ2VuZT1wYXN0ZShleHRfZ2VuZSxjb2xsYXBzZSA9ICIsIikpICU+JSByZW5hbWUoUGxvdD1IM0syN2FjdnNCUkIpICU+JSBtdXRhdGUoQ29tcGFyZT0iSDNLMjdhY19CUkIiKQpTaG93X0gzSzI3bWUzdnNCUkJfSDNwM2NsdXMzQlJCY2x1czMgPC0gU2hvd3Bsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGZpbHRlcihCUkJERUdjbHVzdGVyPT0iMyIpJT4lIHVuZ3JvdXAgJT4lIGdyb3VwX2J5KEgzSzI3bWUzdnNCUkIsdGltZSkgJT4lIHN1bW1hcml6ZShjb3VudD1uKCksZ2VuZT1wYXN0ZShleHRfZ2VuZSxjb2xsYXBzZSA9ICIsIikpICU+JSByZW5hbWUoUGxvdD1IM0syN21lM3ZzQlJCKSAlPiUgbXV0YXRlKENvbXBhcmU9IkgzSzI3bWUzX0JSQiIpClNob3dfQVRBQ3ZzQlJCX0gzcDNjbHVzM0JSQmNsdXMzIDwtIFNob3dwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICU+JSBmaWx0ZXIoQlJCREVHY2x1c3Rlcj09IjMiKSU+JSB1bmdyb3VwICU+JSBncm91cF9ieShBVEFDdnNCUkIsdGltZSkgJT4lIHN1bW1hcml6ZShjb3VudD1uKCksZ2VuZT1wYXN0ZShleHRfZ2VuZSxjb2xsYXBzZSA9ICIsIikpICU+JSByZW5hbWUoUGxvdD1BVEFDdnNCUkIpICU+JSBtdXRhdGUoQ29tcGFyZT0iQVRBQ19CUkIiKQoKU2hvd19fdnNCUkJfSDNwM2NsdXMzQlJCY2x1czMgPC0gYmluZF9yb3dzKFNob3dfSDNwM3ZzQlJCX0gzcDNjbHVzM0JSQmNsdXMzLFNob3dfSDNLNG1lM3ZzQlJCX0gzcDNjbHVzM0JSQmNsdXMzKSAlPiUgYmluZF9yb3dzKFNob3dfSDNLMjdhY3ZzQlJCX0gzcDNjbHVzM0JSQmNsdXMzKSAlPiUgYmluZF9yb3dzKFNob3dfSDNLMjdtZTN2c0JSQl9IM3AzY2x1czNCUkJjbHVzMykgJT4lIGJpbmRfcm93cyhTaG93X0FUQUN2c0JSQl9IM3AzY2x1czNCUkJjbHVzMykgICU+JSBtdXRhdGUodGFyZ2V0PSJIM3AzY2x1czNCUkJjbHVzMyIpICAlPiUgbXV0YXRlKENvdW50PWNhc2Vfd2hlbihQbG90PT0iTm90IFNob3duIn5wYXN0ZSgiKCIsY291bnQsIikiLHNlcD0iIiksVFJVRX5hcy5jaGFyYWN0ZXIoY291bnQpKSkgJT4lIG11dGF0ZShQbG90PWZhY3RvcihQbG90LCBjKCJTaG93biIsIk5vdCBTaG93biIpKSkgJT4lIGFycmFuZ2UoQ29tcGFyZSx0aW1lLFBsb3QpCgoKIyMjIwpTaG93X192c0JSQl9IM3AzY2x1czNBbGwKU2hvd19fdnNCUkJfSDNwM2NsdXMzQlJCY2x1czMKU2hvd19fdnNCUkJfSDNwM2NsdXMzQlJCY2x1czMgJT4lIGZpbHRlcihQbG90PT0iTm90IFNob3duIikKClNob3dfX3ZzQlJCX0gzcDNjbHVzM0FsbCAlPiUgcmVhZHI6OndyaXRlX2NzdigiLi9sb2cyRkMvdGFibGVzL1BMb3RzaG93X0gzcDNjbHVzM0FsbC5jc3YiKQpTaG93X192c0JSQl9IM3AzY2x1czNCUkJjbHVzMyAlPiUgcmVhZHI6OndyaXRlX2NzdigiLi9sb2cyRkMvdGFibGVzL1BMb3RzaG93X0gzcDNjbHVzM0JSQmNsdXMzLmNzdiIpCgpzdW1tYV9fdnNCUkJfSDNwM2NsdXMzQWxsIDwtIFNob3dfX3ZzQlJCX0gzcDNjbHVzM0FsbCAlPiUgdW5ncm91cCgpICU+JSBncm91cF9ieSh0YXJnZXQsIHRpbWUsIENvbXBhcmUpICU+JSBzdW1tYXJpemUoU2hvdz1wYXN0ZShDb3VudCxjb2xsYXBzZSA9ICIgIikpCnN1bW1hX192c0JSQl9IM3AzY2x1czNCUkJjbHVzMyA8LSBTaG93X192c0JSQl9IM3AzY2x1czNCUkJjbHVzMyAlPiUgdW5ncm91cCgpICU+JSBncm91cF9ieSh0YXJnZXQsIHRpbWUsIENvbXBhcmUpICU+JSBzdW1tYXJpemUoU2hvdz1wYXN0ZShDb3VudCxjb2xsYXBzZSA9ICIgIikpCgpzdW1tYV9fdnNCUkJfSDNwM2NsdXMzQWxsICU+JSByZWFkcjo6d3JpdGVfY3N2KCIuL2xvZzJGQy90YWJsZXMvUExvdHNob3dfSDNwM2NsdXMzQWxsX3N1bW1hcnkuY3N2IikKc3VtbWFfX3ZzQlJCX0gzcDNjbHVzM0JSQmNsdXMzICU+JSByZWFkcjo6d3JpdGVfY3N2KCIuL2xvZzJGQy90YWJsZXMvUExvdHNob3dfSDNwM2NsdXMzQlJCY2x1czNfc3VtbWFyeS5jc3YiKQoKCnN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzIDwtIGJpbmRfcm93cyhzdW1tYV9fdnNCUkJfSDNwM2NsdXMzQWxsLHN1bW1hX192c0JSQl9IM3AzY2x1czNCUkJjbHVzMykgJT4lIG11dGF0ZSh0YXJnZXQ9ZmFjdG9yKHRhcmdldCwgYygiSDNwM2NsdXMzQWxsIiwiSDNwM2NsdXMzQlJCY2x1czMiKSkpICU+JSBhcnJhbmdlKENvbXBhcmUsdGltZSx0YXJnZXQpICU+JSBtdXRhdGUoY2x1cz1nc3ViKCJIM3AzY2x1czMiLCIiLHRhcmdldCkpICU+JSB1bmdyb3VwKCkgJT4lIGdyb3VwX2J5KHRpbWUsQ29tcGFyZSkgJT4lIHN1bW1hcml6ZShzaG93PXBhc3RlKFNob3csY29sbGFwc2UgPSAiIC8gIiksQ2x1c3Rlcj1wYXN0ZShjbHVzLGNvbGxhcHNlID0gIiAvICIpKQoKCnN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzICU+JSByZWFkcjo6d3JpdGVfY3N2KCIuL2xvZzJGQy90YWJsZXMvUExvdHNob3dfSDNwM2NsdXMzX0FsbF9hbmRfQlJCY2x1czNfc3VtbWFyeS5jc3YiKQoKc3VtbWFfX3ZzQlJCX0gzcDNjbHVzM19BTExfQlJCY2x1czMKCmBgYAoKCmBgYHtyIHBsb3QgbG9nMkZDIEgzcDNjbHVzMyBjdXQgb2ZmIGRlbnMsIGZpZy53aWR0aD00LGZpZy5oZWlnaHQ9MTB9CgojZGVuc2l0eV9jb2xvcl9sb3cgPC0gIiNFQ0UwMzgiCmRlbnNpdHlfY29sb3JfbG93IDwtICIjRkZGRkZGIgojZGVuc2l0eV9jb2xvcl9oaWdoIDwtICIjMzc3RUI4IgpkZW5zaXR5X2NvbG9yX2hpZ2ggPC0gImJsdWUiCiNkZW5zaXR5X2NvbG9yX2xvdyA8LSAjRkZGRkZGIgojZGVuc2l0eV9jb2xvcl9taWQgPC0gInllbGxvdyIKI2RlbnNpdHlfY29sb3JfaGlnaCA8LSAicmVkIgoKYmluc2l6ZSA8LSA3CgoKcHBwcGxvdHRpdGxlIDwtIHBhc3RlKCJsb2cyIEZDIChEb3ggKyB2cyAtKVxuQlJCIG5vcm1hbGl6ZWQgY291bnQgKFRpbWUsIGF2ZykgPiAiLFNldF9jdXRvZmYsIlxuIEgzLjMgY2x1czM6ICIsbnJvdyh6X0gzcDNjbHVzMyksIiBnZW5lc1xuIFBsb3Q6ICIsSDNwM2NsdXMzY3V0b2ZmLCIgZ2VuZXNcbiBCUkIgY2x1czM6ICAiLEgzcDNjbHVzM2N1dG9mZl9icmJjbHVzMywiIGdlbmVzIixzZXA9IiIpCgoKIyMjCmZjcGxvdCA8LXBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgICU+JSBnZ3Bsb3QoYWVzKHk9QlJCLCB4PUgzcDMpKSAgKyBmYWNldF93cmFwKH50aW1lLG5jb2w9MSkgICsgc3RhdF9kZW5zaXR5MmQoYWVzKGZpbGw9Li5kZW5zaXR5Li4pLCBnZW9tID0gInJhc3RlciIsY29udG91ciA9IEZBTFNFKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gZGVuc2l0eV9jb2xvcl9sb3csIGhpZ2ggPSBkZW5zaXR5X2NvbG9yX2hpZ2gpICArIGdlb21fYWJsaW5lKGludGVyY2VwdD0wLHNsb3BlPTAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV9kZW5zaXR5MmQoYWVzKGNvbG9yPUJSQkRFR2NsdXN0ZXIpLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLHNpemU9MC4xLGFscGhhID0gMC41LCBiaW5zPWJpbnNpemUpICsgZ2VvbV9wb2ludChhZXMoeT1CUkIsIHg9SDNwMyksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyB4bGFiKCJIMy4zIikgKyBnZ3RpdGxlKHBwcHBsb3R0aXRsZSkrIHhsaW0oLTEuMCwgMS4wKSArIHlsaW0oLTIuMCwgMi4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ19ub2xhYmVsX0gzcDNjbHVzM19jdXRvZmZfX0gzcDN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ19IM3AzY2x1czNfY3V0b2ZmX19IM3AzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKCmZjcGxvdCA8LSBmY3Bsb3QgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0JSQmNsdXMzLENvbXBhcmU9PSJIM3AzX0JSQiIpLGFlcyh4PS0xLjAseT0xLjgsbGFiZWw9dGV4dCksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQWxsLENvbXBhcmU9PSJIM3AzX0JSQiIpLGFlcyh4PS0xLjAseT0yLjAsbGFiZWw9dGV4dCksIGNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLCBzZWdtZW50LmNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKHN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzLENvbXBhcmU9PSJIM3AzX0JSQiIpLGFlcyh4PS0xLjAseT0xLjYsbGFiZWw9c2hvdyksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ193aXRoY29ycl9IM3AzY2x1czNfY3V0b2ZmX19IM3AzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CgojIyMKZmNwbG90IDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgICU+JSBnZ3Bsb3QoYWVzKHk9QlJCLCB4PUgzSzRtZTMpKSAgKyBmYWNldF93cmFwKH50aW1lLG5jb2w9MSkgICsgc3RhdF9kZW5zaXR5MmQoYWVzKGZpbGw9Li5kZW5zaXR5Li4pLCBnZW9tID0gInJhc3RlciIsY29udG91ciA9IEZBTFNFKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gZGVuc2l0eV9jb2xvcl9sb3csIGhpZ2ggPSBkZW5zaXR5X2NvbG9yX2hpZ2gpICArIGdlb21fYWJsaW5lKGludGVyY2VwdD0wLHNsb3BlPTAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV9kZW5zaXR5MmQoYWVzKGNvbG9yPUJSQkRFR2NsdXN0ZXIpLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLHNpemU9MC4xLGFscGhhID0gMC41LCBiaW5zPWJpbnNpemUpICsgZ2VvbV9wb2ludChhZXMoeT1CUkIsIHg9SDNLNG1lMyksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyBnZ3RpdGxlKHBwcHBsb3R0aXRsZSkrIHhsaW0oLTEuNSwgMS41KSArIHlsaW0oLTIuMCwgMi4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ19ub2xhYmVsX0gzcDNjbHVzM19jdXRvZmZfX0gzSzRtZTN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ19IM3AzY2x1czNfY3V0b2ZmX19IM0s0bWUzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQlJCY2x1czMsQ29tcGFyZT09IkgzSzRtZTNfQlJCIiksYWVzKHg9LTEuNSx5PTEuOCxsYWJlbD10ZXh0KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNBbGwsQ29tcGFyZT09IkgzSzRtZTNfQlJCIiksYWVzKHg9LTEuNSx5PTIuMCxsYWJlbD10ZXh0KSwgY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsIHNlZ21lbnQuY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoc3VtbWFfX3ZzQlJCX0gzcDNjbHVzM19BTExfQlJCY2x1czMsQ29tcGFyZT09IkgzSzRtZTNfQlJCIiksYWVzKHg9LTEuNSx5PTEuNixsYWJlbD1zaG93KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvbG9nMkZDX3dpdGhjb3JyX0gzcDNjbHVzM19jdXRvZmZfX0gzSzRtZTN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QKCiMjIwpmY3Bsb3QgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAgJT4lIGdncGxvdChhZXMoeT1CUkIsIHg9SDNLMjdhYykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSAgKyBzdGF0X2RlbnNpdHkyZChhZXMoZmlsbD0uLmRlbnNpdHkuLiksIGdlb20gPSAicmFzdGVyIixjb250b3VyID0gRkFMU0UpICsgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBkZW5zaXR5X2NvbG9yX2xvdywgaGlnaCA9IGRlbnNpdHlfY29sb3JfaGlnaCkgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsc2xvcGU9MCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkyZChhZXMoY29sb3I9QlJCREVHY2x1c3RlciksZGF0YT1mX2dlbmVfQlJCY2x1czMsc2l6ZT0wLjEsYWxwaGEgPSAwLjUsIGJpbnM9Ymluc2l6ZSkgKyBnZW9tX3BvaW50KGFlcyh5PUJSQiwgeD1IM0syN2FjKSxhbHBoYSA9IDAuNiwgc2l6ZT0xLjAsIGRhdGE9Zl9nZW5lX0JSQmNsdXMzKSAgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzAwMDAwMCIpKSt0aGVtZV9idygpICsgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSxheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsdmp1c3Q9MS4wKSwgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Iiwgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNSksc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSx0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpKSArIGdndGl0bGUocHBwcGxvdHRpdGxlKSsgeGxpbSgtMS4wLCAxLjApICsgeWxpbSgtMi4wLCAyLjApCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvbG9nMkZDX25vbGFiZWxfSDNwM2NsdXMzX2N1dG9mZl9fSDNLMjdhY3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdCA8LSBmY3Bsb3QgICsgZ2VvbV90ZXh0X3JlcGVsKGFlcyhsYWJlbCA9IGxhYmVsX3RleHQpLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSkKCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvbG9nMkZDX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3YWN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNCUkJjbHVzMyxDb21wYXJlPT0iSDNLMjdhY19CUkIiKSxhZXMoeD0tMS4wLHk9MS44LGxhYmVsPXRleHQpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0FsbCxDb21wYXJlPT0iSDNLMjdhY19CUkIiKSxhZXMoeD0tMS4wLHk9Mi4wLGxhYmVsPXRleHQpLCBjb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCwgc2VnbWVudC5jb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCxzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihzdW1tYV9fdnNCUkJfSDNwM2NsdXMzX0FMTF9CUkJjbHVzMyxDb21wYXJlPT0iSDNLMjdhY19CUkIiKSxhZXMoeD0tMS4wLHk9MS42LGxhYmVsPXNob3cpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9sb2cyRkNfd2l0aGNvcnJfSDNwM2NsdXMzX2N1dG9mZl9fSDNLMjdhY3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdAoKIyMjCmZjcGxvdCA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICAlPiUgZ2dwbG90KGFlcyh5PUJSQiwgeD1IM0syN21lMykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSAgKyBzdGF0X2RlbnNpdHkyZChhZXMoZmlsbD0uLmRlbnNpdHkuLiksIGdlb20gPSAicmFzdGVyIixjb250b3VyID0gRkFMU0UpICsgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBkZW5zaXR5X2NvbG9yX2xvdywgaGlnaCA9IGRlbnNpdHlfY29sb3JfaGlnaCkgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsc2xvcGU9MCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkyZChhZXMoY29sb3I9QlJCREVHY2x1c3RlciksZGF0YT1mX2dlbmVfQlJCY2x1czMsc2l6ZT0wLjEsYWxwaGEgPSAwLjUsIGJpbnM9Ymluc2l6ZSkgKyBnZW9tX3BvaW50KGFlcyh5PUJSQiwgeD1IM0syN21lMyksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyBnZ3RpdGxlKHBwcHBsb3R0aXRsZSkrIHhsaW0oLTEuMCwgMS4wKSArIHlsaW0oLTIuMCwgMi4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ19ub2xhYmVsX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3bWUzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKCmZjcGxvdCA8LSBmY3Bsb3QgICsgZ2VvbV90ZXh0X3JlcGVsKGFlcyhsYWJlbCA9IGxhYmVsX3RleHQpLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSkKCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvbG9nMkZDX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3bWUzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQlJCY2x1czMsQ29tcGFyZT09IkgzSzI3bWUzX0JSQiIpLGFlcyh4PS0xLjAseT0xLjgsbGFiZWw9dGV4dCksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQWxsLENvbXBhcmU9PSJIM0syN21lM19CUkIiKSxhZXMoeD0tMS4wLHk9Mi4wLGxhYmVsPXRleHQpLCBjb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCwgc2VnbWVudC5jb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCxzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihzdW1tYV9fdnNCUkJfSDNwM2NsdXMzX0FMTF9CUkJjbHVzMyxDb21wYXJlPT0iSDNLMjdtZTNfQlJCIiksYWVzKHg9LTEuMCx5PTEuNixsYWJlbD1zaG93KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvbG9nMkZDX3dpdGhjb3JyX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3bWUzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CgojIyMKZmNwbG90IDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGdncGxvdChhZXMoeT1CUkIsIHg9QVRBQykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSAgKyBzdGF0X2RlbnNpdHkyZChhZXMoZmlsbD0uLmRlbnNpdHkuLiksIGdlb20gPSAicmFzdGVyIixjb250b3VyID0gRkFMU0UpICsgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBkZW5zaXR5X2NvbG9yX2xvdywgaGlnaCA9IGRlbnNpdHlfY29sb3JfaGlnaCkgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsc2xvcGU9MCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkyZChhZXMoY29sb3I9QlJCREVHY2x1c3RlciksZGF0YT1mX2dlbmVfQlJCY2x1czMsc2l6ZT0wLjEsYWxwaGEgPSAwLjUsIGJpbnM9Ymluc2l6ZSkgKyBnZW9tX3BvaW50KGFlcyh5PUJSQiwgeD1BVEFDKSxhbHBoYSA9IDAuNiwgc2l6ZT0xLjAsIGRhdGE9Zl9nZW5lX0JSQmNsdXMzKSAgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzAwMDAwMCIpKSt0aGVtZV9idygpICsgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSxheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsdmp1c3Q9MS4wKSwgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Iiwgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNSksc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSx0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpKSArIGdndGl0bGUocHBwcGxvdHRpdGxlKSsgeGxpbSgtMC40LCAwLjQpICsgeWxpbSgtMi4wLCAyLjApCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvbG9nMkZDX25vbGFiZWxfSDNwM2NsdXMzX2N1dG9mZl9fQVRBQ3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCgpmY3Bsb3QgPC0gZmNwbG90ICArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ19IM3AzY2x1czNfY3V0b2ZmX19BVEFDdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKCmZjcGxvdCA8LSBmY3Bsb3QgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0JSQmNsdXMzLENvbXBhcmU9PSJBVEFDX0JSQiIpLGFlcyh4PS0wLjQseT0xLjgsbGFiZWw9dGV4dCksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQWxsLENvbXBhcmU9PSJBVEFDX0JSQiIpLGFlcyh4PS0wLjQseT0yLjAsbGFiZWw9dGV4dCksIGNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLCBzZWdtZW50LmNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKHN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzLENvbXBhcmU9PSJBVEFDX0JSQiIpLGFlcyh4PS0wLjQseT0xLjYsbGFiZWw9c2hvdyksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2xvZzJGQ193aXRoY29ycl9IM3AzY2x1czNfY3V0b2ZmX19BVEFDdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CmBgYAoKCgoKCmBgYHtyIHBsb3QgbG9nMkZDIEgzcDNjbHVzMyBjdXQgb2ZmIGVjLCBmaWcud2lkdGg9NCxmaWcuaGVpZ2h0PTEwfQoKI2RlbnNpdHlfY29sb3JfbG93IDwtICIjRUNFMDM4IgpkZW5zaXR5X2NvbG9yX2xvdyA8LSAiI0ZGRkZGRiIKI2RlbnNpdHlfY29sb3JfaGlnaCA8LSAiIzM3N0VCOCIKZGVuc2l0eV9jb2xvcl9oaWdoIDwtICJibHVlIgojZGVuc2l0eV9jb2xvcl9sb3cgPC0gI0ZGRkZGRiIKI2RlbnNpdHlfY29sb3JfbWlkIDwtICJ5ZWxsb3ciCiNkZW5zaXR5X2NvbG9yX2hpZ2ggPC0gInJlZCIKCmJpbnNpemUgPC0gNwoKCnBwcHBsb3R0aXRsZSA8LSBwYXN0ZSgibG9nMiBGQyAoRG94ICsgdnMgLSlcbkJSQiBub3JtYWxpemVkIGNvdW50IChUaW1lLCBhdmcpID4gIixTZXRfY3V0b2ZmLCJcbiBIMy4zIGNsdXMzOiAiLG5yb3coel9IM3AzY2x1czMpLCIgZ2VuZXNcbiBQbG90OiAiLEgzcDNjbHVzM2N1dG9mZiwiIGdlbmVzXG4gQlJCIGNsdXMzOiAgIixIM3AzY2x1czNjdXRvZmZfYnJiY2x1czMsIiBnZW5lcyIsc2VwPSIiKQoKCiMjIwpmY3Bsb3QgPC1wbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICAlPiUgZ2dwbG90KGFlcyh5PUJSQiwgeD1IM3AzKSkgICsgZmFjZXRfd3JhcCh+dGltZSxuY29sPTEpICArIHN0YXRfZGVuc2l0eTJkKGFlcyhmaWxsPS4uZGVuc2l0eS4uKSwgZ2VvbSA9ICJyYXN0ZXIiLGNvbnRvdXIgPSBGQUxTRSkgKyBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9IGRlbnNpdHlfY29sb3JfbG93LCBoaWdoID0gZGVuc2l0eV9jb2xvcl9oaWdoKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQ9MCxzbG9wZT0wLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIHN0YXRfZWxsaXBzZSh0eXBlID0gIm5vcm0iLGNvbG9yPWRlbnNpdHlfY29sb3JfaGlnaCxzaXplPTAuMikgKyBzdGF0X2VsbGlwc2UodHlwZSA9ICJub3JtIixjb2xvcj0iIzAwMDAwMCIsZGF0YT1mX2dlbmVfQlJCY2x1czMsc2l6ZT0wLjIpICsgZ2VvbV9wb2ludChhZXMoeT1CUkIsIHg9SDNwMyksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyB4bGFiKCJIMy4zIikgKyBnZ3RpdGxlKHBwcHBsb3R0aXRsZSkrIHhsaW0oLTEuMCwgMS4wKSArIHlsaW0oLTIuMCwgMi4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2VsbGlwc2UvbG9nMkZDX2VsbGlwc2Vfbm9sYWJlbF9IM3AzY2x1czNfY3V0b2ZmX19IM3AzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyBnZW9tX3RleHRfcmVwZWwoYWVzKGxhYmVsID0gbGFiZWxfdGV4dCksIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xKQoKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9lbGxpcHNlL2xvZzJGQ19lbGxpcHNlX0gzcDNjbHVzM19jdXRvZmZfX0gzcDN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgoKZmNwbG90IDwtIGZjcGxvdCAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQlJCY2x1czMsQ29tcGFyZT09IkgzcDNfQlJCIiksYWVzKHg9LTEuMCx5PTEuOCxsYWJlbD10ZXh0KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNBbGwsQ29tcGFyZT09IkgzcDNfQlJCIiksYWVzKHg9LTEuMCx5PTIuMCxsYWJlbD10ZXh0KSwgY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsIHNlZ21lbnQuY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoc3VtbWFfX3ZzQlJCX0gzcDNjbHVzM19BTExfQlJCY2x1czMsQ29tcGFyZT09IkgzcDNfQlJCIiksYWVzKHg9LTEuMCx5PTEuNixsYWJlbD1zaG93KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvZWxsaXBzZS9sb2cyRkNfZWxsaXBzZV93aXRoY29ycl9IM3AzY2x1czNfY3V0b2ZmX19IM3AzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CgojIyMKZmNwbG90IDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgICU+JSBnZ3Bsb3QoYWVzKHk9QlJCLCB4PUgzSzRtZTMpKSAgKyBmYWNldF93cmFwKH50aW1lLG5jb2w9MSkgICsgc3RhdF9kZW5zaXR5MmQoYWVzKGZpbGw9Li5kZW5zaXR5Li4pLCBnZW9tID0gInJhc3RlciIsY29udG91ciA9IEZBTFNFKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gZGVuc2l0eV9jb2xvcl9sb3csIGhpZ2ggPSBkZW5zaXR5X2NvbG9yX2hpZ2gpICArIGdlb21fYWJsaW5lKGludGVyY2VwdD0wLHNsb3BlPTAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgc3RhdF9lbGxpcHNlKHR5cGUgPSAibm9ybSIsY29sb3I9ZGVuc2l0eV9jb2xvcl9oaWdoLHNpemU9MC4yKSArIHN0YXRfZWxsaXBzZSh0eXBlID0gIm5vcm0iLGNvbG9yPSIjMDAwMDAwIixkYXRhPWZfZ2VuZV9CUkJjbHVzMyxzaXplPTAuMikgKyBnZW9tX3BvaW50KGFlcyh5PUJSQiwgeD1IM0s0bWUzKSxhbHBoYSA9IDAuNiwgc2l6ZT0xLjAsIGRhdGE9Zl9nZW5lX0JSQmNsdXMzKSAgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzAwMDAwMCIpKSt0aGVtZV9idygpICsgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSxheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsdmp1c3Q9MS4wKSwgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Iiwgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNSksc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSx0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpKSArIGdndGl0bGUocHBwcGxvdHRpdGxlKSsgeGxpbSgtMS41LCAxLjUpICsgeWxpbSgtMi4wLCAyLjApCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvZWxsaXBzZS9sb2cyRkNfZWxsaXBzZV9ub2xhYmVsX0gzcDNjbHVzM19jdXRvZmZfX0gzSzRtZTN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2VsbGlwc2UvbG9nMkZDX2VsbGlwc2VfSDNwM2NsdXMzX2N1dG9mZl9fSDNLNG1lM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdCA8LSBmY3Bsb3QgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0JSQmNsdXMzLENvbXBhcmU9PSJIM0s0bWUzX0JSQiIpLGFlcyh4PS0xLjUseT0xLjgsbGFiZWw9dGV4dCksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQWxsLENvbXBhcmU9PSJIM0s0bWUzX0JSQiIpLGFlcyh4PS0xLjUseT0yLjAsbGFiZWw9dGV4dCksIGNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLCBzZWdtZW50LmNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKHN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzLENvbXBhcmU9PSJIM0s0bWUzX0JSQiIpLGFlcyh4PS0xLjUseT0xLjYsbGFiZWw9c2hvdyksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2VsbGlwc2UvbG9nMkZDX2VsbGlwc2Vfd2l0aGNvcnJfSDNwM2NsdXMzX2N1dG9mZl9fSDNLNG1lM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdAoKIyMjCmZjcGxvdCA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICAlPiUgZ2dwbG90KGFlcyh5PUJSQiwgeD1IM0syN2FjKSkgICsgZmFjZXRfd3JhcCh+dGltZSxuY29sPTEpICArIHN0YXRfZGVuc2l0eTJkKGFlcyhmaWxsPS4uZGVuc2l0eS4uKSwgZ2VvbSA9ICJyYXN0ZXIiLGNvbnRvdXIgPSBGQUxTRSkgKyBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9IGRlbnNpdHlfY29sb3JfbG93LCBoaWdoID0gZGVuc2l0eV9jb2xvcl9oaWdoKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQ9MCxzbG9wZT0wLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIHN0YXRfZWxsaXBzZSh0eXBlID0gIm5vcm0iLGNvbG9yPWRlbnNpdHlfY29sb3JfaGlnaCxzaXplPTAuMikgKyBzdGF0X2VsbGlwc2UodHlwZSA9ICJub3JtIixjb2xvcj0iIzAwMDAwMCIsZGF0YT1mX2dlbmVfQlJCY2x1czMsc2l6ZT0wLjIpICsgZ2VvbV9wb2ludChhZXMoeT1CUkIsIHg9SDNLMjdhYyksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyBnZ3RpdGxlKHBwcHBsb3R0aXRsZSkrIHhsaW0oLTEuMCwgMS4wKSArIHlsaW0oLTIuMCwgMi4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2VsbGlwc2UvbG9nMkZDX2VsbGlwc2Vfbm9sYWJlbF9IM3AzY2x1czNfY3V0b2ZmX19IM0syN2FjdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyBnZW9tX3RleHRfcmVwZWwoYWVzKGxhYmVsID0gbGFiZWxfdGV4dCksIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xKQoKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9lbGxpcHNlL2xvZzJGQ19lbGxpcHNlX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3YWN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNCUkJjbHVzMyxDb21wYXJlPT0iSDNLMjdhY19CUkIiKSxhZXMoeD0tMS4wLHk9MS44LGxhYmVsPXRleHQpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0FsbCxDb21wYXJlPT0iSDNLMjdhY19CUkIiKSxhZXMoeD0tMS4wLHk9Mi4wLGxhYmVsPXRleHQpLCBjb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCwgc2VnbWVudC5jb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCxzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihzdW1tYV9fdnNCUkJfSDNwM2NsdXMzX0FMTF9CUkJjbHVzMyxDb21wYXJlPT0iSDNLMjdhY19CUkIiKSxhZXMoeD0tMS4wLHk9MS42LGxhYmVsPXNob3cpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9lbGxpcHNlL2xvZzJGQ19lbGxpcHNlX3dpdGhjb3JyX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3YWN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QKCiMjIwpmY3Bsb3QgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAgJT4lIGdncGxvdChhZXMoeT1CUkIsIHg9SDNLMjdtZTMpKSAgKyBmYWNldF93cmFwKH50aW1lLG5jb2w9MSkgICsgc3RhdF9kZW5zaXR5MmQoYWVzKGZpbGw9Li5kZW5zaXR5Li4pLCBnZW9tID0gInJhc3RlciIsY29udG91ciA9IEZBTFNFKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gZGVuc2l0eV9jb2xvcl9sb3csIGhpZ2ggPSBkZW5zaXR5X2NvbG9yX2hpZ2gpICArIGdlb21fYWJsaW5lKGludGVyY2VwdD0wLHNsb3BlPTAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgc3RhdF9lbGxpcHNlKHR5cGUgPSAibm9ybSIsY29sb3I9ZGVuc2l0eV9jb2xvcl9oaWdoLHNpemU9MC4yKSArIHN0YXRfZWxsaXBzZSh0eXBlID0gIm5vcm0iLGNvbG9yPSIjMDAwMDAwIixkYXRhPWZfZ2VuZV9CUkJjbHVzMyxzaXplPTAuMikgKyBnZW9tX3BvaW50KGFlcyh5PUJSQiwgeD1IM0syN21lMyksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyBnZ3RpdGxlKHBwcHBsb3R0aXRsZSkrIHhsaW0oLTEuMCwgMS4wKSArIHlsaW0oLTIuMCwgMi4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2VsbGlwc2UvbG9nMkZDX2VsbGlwc2Vfbm9sYWJlbF9IM3AzY2x1czNfY3V0b2ZmX19IM0syN21lM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCgpmY3Bsb3QgPC0gZmNwbG90ICArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2VsbGlwc2UvbG9nMkZDX2VsbGlwc2VfSDNwM2NsdXMzX2N1dG9mZl9fSDNLMjdtZTN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNCUkJjbHVzMyxDb21wYXJlPT0iSDNLMjdtZTNfQlJCIiksYWVzKHg9LTEuMCx5PTEuOCxsYWJlbD10ZXh0KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNBbGwsQ29tcGFyZT09IkgzSzI3bWUzX0JSQiIpLGFlcyh4PS0xLjAseT0yLjAsbGFiZWw9dGV4dCksIGNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLCBzZWdtZW50LmNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKHN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzLENvbXBhcmU9PSJIM0syN21lM19CUkIiKSxhZXMoeD0tMS4wLHk9MS42LGxhYmVsPXNob3cpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9lbGxpcHNlL2xvZzJGQ19lbGxpcHNlX3dpdGhjb3JyX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3bWUzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CgojIyMKZmNwbG90IDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgJT4lIGdncGxvdChhZXMoeT1CUkIsIHg9QVRBQykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSAgKyBzdGF0X2RlbnNpdHkyZChhZXMoZmlsbD0uLmRlbnNpdHkuLiksIGdlb20gPSAicmFzdGVyIixjb250b3VyID0gRkFMU0UpICsgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBkZW5zaXR5X2NvbG9yX2xvdywgaGlnaCA9IGRlbnNpdHlfY29sb3JfaGlnaCkgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsc2xvcGU9MCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBzdGF0X2VsbGlwc2UodHlwZSA9ICJub3JtIixjb2xvcj1kZW5zaXR5X2NvbG9yX2hpZ2gsc2l6ZT0wLjIpICsgc3RhdF9lbGxpcHNlKHR5cGUgPSAibm9ybSIsY29sb3I9IiMwMDAwMDAiLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLHNpemU9MC4yKSArIGdlb21fcG9pbnQoYWVzKHk9QlJCLCB4PUFUQUMpLGFscGhhID0gMC42LCBzaXplPTEuMCwgZGF0YT1mX2dlbmVfQlJCY2x1czMpICArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDAwMDAwIikpK3RoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSx2anVzdD0xLjApLCBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE1KSxzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9OCkscGFuZWwuZ3JpZD1lbGVtZW50X2JsYW5rKCkpICsgZ2d0aXRsZShwcHBwbG90dGl0bGUpKyB4bGltKC0wLjQsIDAuNCkgKyB5bGltKC0yLjAsIDIuMCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9lbGxpcHNlL2xvZzJGQ19lbGxpcHNlX25vbGFiZWxfSDNwM2NsdXMzX2N1dG9mZl9fQVRBQ3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCgpmY3Bsb3QgPC0gZmNwbG90ICArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2VsbGlwc2UvbG9nMkZDX2VsbGlwc2VfSDNwM2NsdXMzX2N1dG9mZl9fQVRBQ3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCgpmY3Bsb3QgPC0gZmNwbG90ICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNCUkJjbHVzMyxDb21wYXJlPT0iQVRBQ19CUkIiKSxhZXMoeD0tMC40LHk9MS44LGxhYmVsPXRleHQpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0FsbCxDb21wYXJlPT0iQVRBQ19CUkIiKSxhZXMoeD0tMC40LHk9Mi4wLGxhYmVsPXRleHQpLCBjb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCwgc2VnbWVudC5jb2xvciA9IGRlbnNpdHlfY29sb3JfaGlnaCxzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihzdW1tYV9fdnNCUkJfSDNwM2NsdXMzX0FMTF9CUkJjbHVzMyxDb21wYXJlPT0iQVRBQ19CUkIiKSxhZXMoeD0tMC40LHk9MS42LGxhYmVsPXNob3cpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9lbGxpcHNlL2xvZzJGQ19lbGxpcHNlX3dpdGhjb3JyX0gzcDNjbHVzM19jdXRvZmZfX0FUQUN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QKYGBgCgoKCkZvciBDaGVjawoKYGBge3IgcGxvdCBsb2cyRkMgSDNwM2NsdXMzIGN1dCBvZmYgZGVucyBDaGVjaywgZmlnLndpZHRoPTQsZmlnLmhlaWdodD0xMH0KCiNkZW5zaXR5X2NvbG9yX2xvdyA8LSAiI0VDRTAzOCIKZGVuc2l0eV9jb2xvcl9sb3cgPC0gIiNGRkZGRkYiCiNkZW5zaXR5X2NvbG9yX2hpZ2ggPC0gIiMzNzdFQjgiCmRlbnNpdHlfY29sb3JfaGlnaCA8LSAiYmx1ZSIKI2RlbnNpdHlfY29sb3JfbG93IDwtICNGRkZGRkYiCiNkZW5zaXR5X2NvbG9yX21pZCA8LSAieWVsbG93IgojZGVuc2l0eV9jb2xvcl9oaWdoIDwtICJyZWQiCgpiaW5zaXplIDwtIDcKCgpwcHBwbG90dGl0bGUgPC0gcGFzdGUoImxvZzIgRkMgKERveCArIHZzIC0pXG5CUkIgbm9ybWFsaXplZCBjb3VudCAoVGltZSwgYXZnKSA+ICIsU2V0X2N1dG9mZiwiXG4gSDMuMyBjbHVzMzogIixucm93KHpfSDNwM2NsdXMzKSwiIGdlbmVzXG4gUGxvdDogIixIM3AzY2x1czNjdXRvZmYsIiBnZW5lc1xuIEJSQiBjbHVzMzogICIsSDNwM2NsdXMzY3V0b2ZmX2JyYmNsdXMzLCIgZ2VuZXMiLHNlcD0iIikKCgojIyMKZmNwbG90IDwtcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAgJT4lIGdncGxvdChhZXMoeT1CUkIsIHg9SDNwMykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSAgKyBzdGF0X2RlbnNpdHkyZChhZXMoZmlsbD0uLmRlbnNpdHkuLiksIGdlb20gPSAicmFzdGVyIixjb250b3VyID0gRkFMU0UpICsgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBkZW5zaXR5X2NvbG9yX2xvdywgaGlnaCA9IGRlbnNpdHlfY29sb3JfaGlnaCkgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsc2xvcGU9MCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkyZChhZXMoY29sb3I9QlJCREVHY2x1c3RlciksZGF0YT1mX2dlbmVfQlJCY2x1czMsc2l6ZT0wLjEsYWxwaGEgPSAwLjUsIGJpbnM9Ymluc2l6ZSkgKyBnZW9tX3BvaW50KGFlcyh5PUJSQiwgeD1IM3AzLCBjb2xvcj1CUkJERUdjbHVzdGVyLHNoYXBlPXNoYXBlKSxhbHBoYSA9IDAuNiwgc2l6ZT0xLjAsIGRhdGE9Zl9nZW5lX0JSQmNsdXMzKSAgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzAwMDAwMCIpKSt0aGVtZV9idygpICsgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSxheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsdmp1c3Q9MS4wKSwgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Iiwgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNSksc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSx0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YygyMSwgMTkpKSArIHhsYWIoIkgzLjMiKSArIGdndGl0bGUocHBwcGxvdHRpdGxlKSAgKyBnZW9tX3RleHRfcmVwZWwoYWVzKGxhYmVsID0gbGFiZWxfdGV4dCksIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL0Zvcl9DaGVjay9sb2cyRkNfQ2hlY2tfbm9saW1pdF9IM3AzY2x1czNfY3V0b2ZmX19IM3AzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyB4bGltKC0xLjAsIDEuMCkgKyB5bGltKC0yLjAsIDIuMCkKCiNmY3Bsb3QKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL0Zvcl9DaGVjay9sb2cyRkNfQ2hlY2tfSDNwM2NsdXMzX2N1dG9mZl9fSDNwM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdCA8LSBmY3Bsb3QgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0JSQmNsdXMzLENvbXBhcmU9PSJIM3AzX0JSQiIpLGFlcyh4PS0xLjAseT0xLjgsbGFiZWw9dGV4dCksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQWxsLENvbXBhcmU9PSJIM3AzX0JSQiIpLGFlcyh4PS0xLjAseT0yLjAsbGFiZWw9dGV4dCksIGNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLCBzZWdtZW50LmNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKHN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzLENvbXBhcmU9PSJIM3AzX0JSQiIpLGFlcyh4PS0xLjAseT0xLjYsbGFiZWw9c2hvdyksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL0Zvcl9DaGVjay9sb2cyRkNfQ2hlY2tfd2l0aGNvcnJfSDNwM2NsdXMzX2N1dG9mZl9fSDNwM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdAojIyMKZmNwbG90IDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgICU+JSBnZ3Bsb3QoYWVzKHk9QlJCLCB4PUgzSzRtZTMpKSAgKyBmYWNldF93cmFwKH50aW1lLG5jb2w9MSkgICsgc3RhdF9kZW5zaXR5MmQoYWVzKGZpbGw9Li5kZW5zaXR5Li4pLCBnZW9tID0gInJhc3RlciIsY29udG91ciA9IEZBTFNFKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gZGVuc2l0eV9jb2xvcl9sb3csIGhpZ2ggPSBkZW5zaXR5X2NvbG9yX2hpZ2gpICArIGdlb21fYWJsaW5lKGludGVyY2VwdD0wLHNsb3BlPTAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV9kZW5zaXR5MmQoYWVzKGNvbG9yPUJSQkRFR2NsdXN0ZXIpLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLHNpemU9MC4xLGFscGhhID0gMC41LCBiaW5zPWJpbnNpemUpICsgZ2VvbV9wb2ludChhZXMoeT1CUkIsIHg9SDNLNG1lMywgY29sb3I9QlJCREVHY2x1c3RlcixzaGFwZT1zaGFwZSksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPWMoMjEsIDE5KSkgICsgZ2d0aXRsZShwcHBwbG90dGl0bGUpICArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvRm9yX0NoZWNrL2xvZzJGQ19DaGVja19ub2xpbWl0X0gzcDNjbHVzM19jdXRvZmZfX0gzSzRtZTN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArIHhsaW0oLTEuNSwgMS41KSArIHlsaW0oLTIuMCwgMi4wKQoKI2ZjcGxvdApnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvRm9yX0NoZWNrL2xvZzJGQ19DaGVja19IM3AzY2x1czNfY3V0b2ZmX19IM0s0bWUzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQlJCY2x1czMsQ29tcGFyZT09IkgzSzRtZTNfQlJCIiksYWVzKHg9LTEuNSx5PTEuOCxsYWJlbD10ZXh0KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNBbGwsQ29tcGFyZT09IkgzSzRtZTNfQlJCIiksYWVzKHg9LTEuNSx5PTIuMCxsYWJlbD10ZXh0KSwgY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsIHNlZ21lbnQuY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgp44CAKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKHN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzLENvbXBhcmU9PSJIM0s0bWUzX0JSQiIpLGFlcyh4PS0xLjUseT0xLjYsbGFiZWw9c2hvdyksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL0Zvcl9DaGVjay9sb2cyRkNfQ2hlY2tfd2l0aGNvcnJfSDNwM2NsdXMzX2N1dG9mZl9fSDNLNG1lM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdAojIyMKZmNwbG90IDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgICU+JSBnZ3Bsb3QoYWVzKHk9QlJCLCB4PUgzSzI3YWMpKSAgKyBmYWNldF93cmFwKH50aW1lLG5jb2w9MSkgICsgc3RhdF9kZW5zaXR5MmQoYWVzKGZpbGw9Li5kZW5zaXR5Li4pLCBnZW9tID0gInJhc3RlciIsY29udG91ciA9IEZBTFNFKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gZGVuc2l0eV9jb2xvcl9sb3csIGhpZ2ggPSBkZW5zaXR5X2NvbG9yX2hpZ2gpICArIGdlb21fYWJsaW5lKGludGVyY2VwdD0wLHNsb3BlPTAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV9kZW5zaXR5MmQoYWVzKGNvbG9yPUJSQkRFR2NsdXN0ZXIpLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLHNpemU9MC4xLGFscGhhID0gMC41LCBiaW5zPWJpbnNpemUpICsgZ2VvbV9wb2ludChhZXMoeT1CUkIsIHg9SDNLMjdhYywgY29sb3I9QlJCREVHY2x1c3RlcixzaGFwZT1zaGFwZSksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDIxLCAxOSkpICArIGdndGl0bGUocHBwcGxvdHRpdGxlKSArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvRm9yX0NoZWNrL2xvZzJGQ19DaGVja19ub2xpbWl0X0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3YWN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QgPC0gZmNwbG90ICArIHhsaW0oLTEuMCwgMS4wKSArIHlsaW0oLTIuMCwgMi4wKQoKI2ZjcGxvdApnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvRm9yX0NoZWNrL2xvZzJGQ19DaGVja19IM3AzY2x1czNfY3V0b2ZmX19IM0syN2FjdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQlJCY2x1czMsQ29tcGFyZT09IkgzSzI3YWNfQlJCIiksYWVzKHg9LTEuMCx5PTEuOCxsYWJlbD10ZXh0KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpICArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoQ29ydGVzdF9IM3AzY2x1czNBbGwsQ29tcGFyZT09IkgzSzI3YWNfQlJCIiksYWVzKHg9LTEuMCx5PTIuMCxsYWJlbD10ZXh0KSwgY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsIHNlZ21lbnQuY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgp44CAICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihzdW1tYV9fdnNCUkJfSDNwM2NsdXMzX0FMTF9CUkJjbHVzMyxDb21wYXJlPT0iSDNLMjdhY19CUkIiKSxhZXMoeD0tMS4wLHk9MS42LGxhYmVsPXNob3cpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9Gb3JfQ2hlY2svbG9nMkZDX0NoZWNrX3dpdGhjb3JyX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3YWN2c0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMTEsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QKIyMjCmZjcGxvdCA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICAlPiUgZ2dwbG90KGFlcyh5PUJSQiwgeD1IM0syN21lMykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSAgKyBzdGF0X2RlbnNpdHkyZChhZXMoZmlsbD0uLmRlbnNpdHkuLiksIGdlb20gPSAicmFzdGVyIixjb250b3VyID0gRkFMU0UpICsgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBkZW5zaXR5X2NvbG9yX2xvdywgaGlnaCA9IGRlbnNpdHlfY29sb3JfaGlnaCkgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsc2xvcGU9MCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkyZChhZXMoY29sb3I9QlJCREVHY2x1c3RlciksZGF0YT1mX2dlbmVfQlJCY2x1czMsc2l6ZT0wLjEsYWxwaGEgPSAwLjUsIGJpbnM9Ymluc2l6ZSkgKyBnZW9tX3BvaW50KGFlcyh5PUJSQiwgeD1IM0syN21lMywgY29sb3I9QlJCREVHY2x1c3RlcixzaGFwZT1zaGFwZSksYWxwaGEgPSAwLjYsIHNpemU9MS4wLCBkYXRhPWZfZ2VuZV9CUkJjbHVzMykgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDAwMDAiKSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDIxLCAxOSkpICArIGdndGl0bGUocHBwcGxvdHRpdGxlKSAgKyBnZW9tX3RleHRfcmVwZWwoYWVzKGxhYmVsID0gbGFiZWxfdGV4dCksIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL0Zvcl9DaGVjay9sb2cyRkNfQ2hlY2tfbm9saW1pdF9IM3AzY2x1czNfY3V0b2ZmX19IM0syN21lM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdCA8LSBmY3Bsb3QgICArIHhsaW0oLTEuMCwgMS4wKSArIHlsaW0oLTIuMCwgMi4wKQoKI2ZjcGxvdApnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvRm9yX0NoZWNrL2xvZzJGQ19DaGVja19IM3AzY2x1czNfY3V0b2ZmX19IM0syN21lM3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdCA8LSBmY3Bsb3QgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0JSQmNsdXMzLENvbXBhcmU9PSJIM0syN21lM19CUkIiKSxhZXMoeD0tMS4wLHk9MS44LGxhYmVsPXRleHQpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0FsbCxDb21wYXJlPT0iSDNLMjdtZTNfQlJCIiksYWVzKHg9LTEuMCx5PTIuMCxsYWJlbD10ZXh0KSwgY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsIHNlZ21lbnQuY29sb3IgPSBkZW5zaXR5X2NvbG9yX2hpZ2gsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgp44CAKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKHN1bW1hX192c0JSQl9IM3AzY2x1czNfQUxMX0JSQmNsdXMzLENvbXBhcmU9PSJIM0syN21lM19CUkIiKSxhZXMoeD0tMS4wLHk9MS42LGxhYmVsPXNob3cpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEsc2l6ZSA9IDEuOCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9Gb3JfQ2hlY2svbG9nMkZDX0NoZWNrX3dpdGhjb3JyX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3bWUzdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CiMjIwpmY3Bsb3QgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZ2dwbG90KGFlcyh5PUJSQiwgeD1BVEFDKSkgICsgZmFjZXRfd3JhcCh+dGltZSxuY29sPTEpICArIHN0YXRfZGVuc2l0eTJkKGFlcyhmaWxsPS4uZGVuc2l0eS4uKSwgZ2VvbSA9ICJyYXN0ZXIiLGNvbnRvdXIgPSBGQUxTRSkgKyBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9IGRlbnNpdHlfY29sb3JfbG93LCBoaWdoID0gZGVuc2l0eV9jb2xvcl9oaWdoKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQ9MCxzbG9wZT0wLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fZGVuc2l0eTJkKGFlcyhjb2xvcj1CUkJERUdjbHVzdGVyKSxkYXRhPWZfZ2VuZV9CUkJjbHVzMyxzaXplPTAuMSxhbHBoYSA9IDAuNSwgYmlucz1iaW5zaXplKSArIGdlb21fcG9pbnQoYWVzKHk9QlJCLCB4PUFUQUMsIGNvbG9yPUJSQkRFR2NsdXN0ZXIsc2hhcGU9c2hhcGUpLGFscGhhID0gMC42LCBzaXplPTEuMCwgZGF0YT1mX2dlbmVfQlJCY2x1czMpICArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDAwMDAwIikpK3RoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSx2anVzdD0xLjApLCBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE1KSxzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9OCkscGFuZWwuZ3JpZD1lbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDIxLCAxOSkpICArIGdndGl0bGUocHBwcGxvdHRpdGxlKSArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBsYWJlbF90ZXh0KSwgc2VnbWVudC5jb2xvciA9ICIjMDAwMDAwIixzZWdtZW50LnNpemUgPSAwLjEpIAoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL0Zvcl9DaGVjay9sb2cyRkNfQ2hlY2tfbm9saW1pdF9IM3AzY2x1czNfY3V0b2ZmX19BVEFDdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90IDwtIGZjcGxvdCAgKyB4bGltKC0wLjQsIDAuNCkgKyB5bGltKC0yLjAsIDIuMCkKCiNmY3Bsb3QKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL0Zvcl9DaGVjay9sb2cyRkNfQ2hlY2tfSDNwM2NsdXMzX2N1dG9mZl9fQVRBQ3ZzQlJCLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAxMSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdCA8LSBmY3Bsb3QgICsgIGdlb21fdGV4dF9yZXBlbChkYXRhPWZpbHRlcihDb3J0ZXN0X0gzcDNjbHVzM0JSQmNsdXMzLENvbXBhcmU9PSJBVEFDX0JSQiIpLGFlcyh4PS0wLjQseT0xLjgsbGFiZWw9dGV4dCksIGNvbG9yID0gIiMwMDAwMDAiLCBzZWdtZW50LmNvbG9yID0gIiMwMDAwMDAiLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSAgKyAgZ2VvbV90ZXh0X3JlcGVsKGRhdGE9ZmlsdGVyKENvcnRlc3RfSDNwM2NsdXMzQWxsLENvbXBhcmU9PSJBVEFDX0JSQiIpLGFlcyh4PS0wLjQseT0yLjAsbGFiZWw9dGV4dCksIGNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLCBzZWdtZW50LmNvbG9yID0gZGVuc2l0eV9jb2xvcl9oaWdoLHNlZ21lbnQuc2l6ZSA9IDAuMSxzaXplID0gMS44KSArICBnZW9tX3RleHRfcmVwZWwoZGF0YT1maWx0ZXIoc3VtbWFfX3ZzQlJCX0gzcDNjbHVzM19BTExfQlJCY2x1czMsQ29tcGFyZT09IkFUQUNfQlJCIiksYWVzKHg9LTAuNCx5PTEuNixsYWJlbD1zaG93KSwgY29sb3IgPSAiIzAwMDAwMCIsIHNlZ21lbnQuY29sb3IgPSAiIzAwMDAwMCIsc2VnbWVudC5zaXplID0gMC4xLHNpemUgPSAxLjgpCgpnZ3NhdmUocGxvdD1mY3Bsb3QsZmlsZT0iLi9sb2cyRkMvRm9yX0NoZWNrL2xvZzJGQ19DaGVja193aXRoY29ycl9IM3AzY2x1czNfY3V0b2ZmX19BVEFDdnNCUkIucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDExLCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CmBgYAoKCgoKMjAyMDA4MTfov73liqAKCmBgYHtyIHBsb3QgbG9nMkZDIEgzcDNjbHVzMyBoaXN0Z3JhbSBkZW5zLCBmaWcud2lkdGg9NCxmaWcuaGVpZ2h0PTR9CgojZGVuc2l0eV9jb2xvcl9sb3cgPC0gIiNFQ0UwMzgiCmRlbnNpdHlfY29sb3JfbG93IDwtICIjRkZGRkZGIgojZGVuc2l0eV9jb2xvcl9oaWdoIDwtICIjMzc3RUI4IgpkZW5zaXR5X2NvbG9yX2hpZ2ggPC0gImJsdWUiCiNkZW5zaXR5X2NvbG9yX2xvdyA8LSAjRkZGRkZGIgojZGVuc2l0eV9jb2xvcl9taWQgPC0gInllbGxvdyIKI2RlbnNpdHlfY29sb3JfaGlnaCA8LSAicmVkIgoKYmluc2l6ZSA8LSA3CgoKcHBwcGxvdHRpdGxlIDwtIHBhc3RlKCJsb2cyIEZDIChEb3ggKyB2cyAtKVxuQlJCIG5vcm1hbGl6ZWQgY291bnQgKFRpbWUsIGF2ZykgPiAiLFNldF9jdXRvZmYsIlxuIEgzLjMgY2x1czM6ICIsbnJvdyh6X0gzcDNjbHVzMyksIiBnZW5lc1xuIFBsb3Q6ICIsSDNwM2NsdXMzY3V0b2ZmLCIgZ2VuZXNcbiBCUkIgY2x1czM6ICAiLEgzcDNjbHVzM2N1dG9mZl9icmJjbHVzMywiIGdlbmVzIixzZXA9IiIpCgojIyMKZmNwbG90IDwtcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZ2dwbG90KGFlcyh4PUJSQikpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkoZmlsbD1kZW5zaXR5X2NvbG9yX2hpZ2gsY29sb3I9ZGVuc2l0eV9jb2xvcl9oaWdoLGFscGhhPTAuNSkgKyBnZW9tX2RlbnNpdHkoZmlsbD0iIzAwMDAwMCIsY29sb3I9IiMwMDAwMDAiLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLGFscGhhPTAuNSkgK3RoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTgpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkrIHhsaW0oLTIuMCwgMi4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2hpc3Rsb2cyRkNfX0gzcDNjbHVzM19jdXRvZmZfX0JSQi5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMy41LCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CgojIyMKZmNwbG90IDwtcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAlPiUgZ2dwbG90KGFlcyh4PUgzcDMpKSAgKyBmYWNldF93cmFwKH50aW1lLG5jb2w9MSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLGNvbG91cj0iIzAwMDAwMCIsc2l6ZT0wLjIpICsgZ2VvbV9kZW5zaXR5KGZpbGw9ZGVuc2l0eV9jb2xvcl9oaWdoLGNvbG9yPWRlbnNpdHlfY29sb3JfaGlnaCxhbHBoYT0wLjUpICsgZ2VvbV9kZW5zaXR5KGZpbGw9IiMwMDAwMDAiLGNvbG9yPSIjMDAwMDAwIixkYXRhPWZfZ2VuZV9CUkJjbHVzMyxhbHBoYT0wLjUpICt0aGVtZV9idygpICsgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSxheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSx2anVzdD0xLjApLCBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE1KSxzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9OCkscGFuZWwuZ3JpZD1lbGVtZW50X2JsYW5rKCkpICsgeGxhYigiSDMuMyIpKyB4bGltKC0xLjAsIDEuMCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9oaXN0bG9nMkZDX19IM3AzY2x1czNfY3V0b2ZmX19IM3AzLnBkZiIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSAzLjUsIGRwaSA9IDM2MCwgbGltaXRzaXplID0gRkFMU0UpCgpmY3Bsb3QKCiMjIwpmY3Bsb3QgPC0gcGxvdF9hbGxfRkNfY3V0b2ZmX0gzcDNjbHVzMyAgICU+JSBnZ3Bsb3QoYWVzKHg9SDNLNG1lMykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkoZmlsbD1kZW5zaXR5X2NvbG9yX2hpZ2gsY29sb3I9ZGVuc2l0eV9jb2xvcl9oaWdoLGFscGhhPTAuNSkgKyBnZW9tX2RlbnNpdHkoZmlsbD0iIzAwMDAwMCIsY29sb3I9IiMwMDAwMDAiLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLGFscGhhPTAuNSkgK3RoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTgpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkrIHhsaW0oLTEuNSwgMS41KQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2hpc3Rsb2cyRkNfX0gzcDNjbHVzM19jdXRvZmZfX0gzSzRtZTMucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDMuNSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdAoKIyMjCmZjcGxvdCA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICAgJT4lIGdncGxvdChhZXMoeD1IM0syN2FjKSkgICsgZmFjZXRfd3JhcCh+dGltZSxuY29sPTEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCxjb2xvdXI9IiMwMDAwMDAiLHNpemU9MC4yKSArIGdlb21fZGVuc2l0eShmaWxsPWRlbnNpdHlfY29sb3JfaGlnaCxjb2xvcj1kZW5zaXR5X2NvbG9yX2hpZ2gsYWxwaGE9MC41KSArIGdlb21fZGVuc2l0eShmaWxsPSIjMDAwMDAwIixjb2xvcj0iIzAwMDAwMCIsZGF0YT1mX2dlbmVfQlJCY2x1czMsYWxwaGE9MC41KSArdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9OCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsdmp1c3Q9MS4wKSwgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Iiwgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNSksc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSx0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpKSArIHhsaW0oLTEuMCwgMS4wKQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2hpc3Rsb2cyRkNfX0gzcDNjbHVzM19jdXRvZmZfX0gzSzI3YWMucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDMuNSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCmZjcGxvdAoKIyMjCmZjcGxvdCA8LSBwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzICAgJT4lIGdncGxvdChhZXMoeD1IM0syN21lMykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkoZmlsbD1kZW5zaXR5X2NvbG9yX2hpZ2gsY29sb3I9ZGVuc2l0eV9jb2xvcl9oaWdoLGFscGhhPTAuNSkgKyBnZW9tX2RlbnNpdHkoZmlsbD0iIzAwMDAwMCIsY29sb3I9IiMwMDAwMDAiLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLGFscGhhPTAuNSkgK3RoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTgpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHZqdXN0PTEuMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTUpLHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04KSxwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSkgKyB4bGltKC0xLjAsIDEuMCkKCmdnc2F2ZShwbG90PWZjcGxvdCxmaWxlPSIuL2xvZzJGQy9oaXN0bG9nMkZDX19IM3AzY2x1czNfY3V0b2ZmX19IM0syN21lMy5wZGYiLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gMy41LCBkcGkgPSAzNjAsIGxpbWl0c2l6ZSA9IEZBTFNFKQoKZmNwbG90CgojIyMKZmNwbG90IDwtIHBsb3RfYWxsX0ZDX2N1dG9mZl9IM3AzY2x1czMgICU+JSBnZ3Bsb3QoYWVzKHg9QVRBQykpICArIGZhY2V0X3dyYXAofnRpbWUsbmNvbD0xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsY29sb3VyPSIjMDAwMDAwIixzaXplPTAuMikgKyBnZW9tX2RlbnNpdHkoZmlsbD1kZW5zaXR5X2NvbG9yX2hpZ2gsY29sb3I9ZGVuc2l0eV9jb2xvcl9oaWdoLGFscGhhPTAuNSkgKyBnZW9tX2RlbnNpdHkoZmlsbD0iIzAwMDAwMCIsY29sb3I9IiMwMDAwMDAiLGRhdGE9Zl9nZW5lX0JSQmNsdXMzLGFscGhhPTAuNSkrdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9OCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsdmp1c3Q9MS4wKSwgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Iiwgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNSksc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSx0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpKSArIHhsaW0oLTAuNCwgMC40KQoKZ2dzYXZlKHBsb3Q9ZmNwbG90LGZpbGU9Ii4vbG9nMkZDL2hpc3Rsb2cyRkNfX0gzcDNjbHVzM19jdXRvZmZfX0FUQUMucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDMuNSwgZHBpID0gMzYwLCBsaW1pdHNpemUgPSBGQUxTRSkKCgpmY3Bsb3QKYGBgCgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMg44Kv44Op44K544K/44Oq44Oz44KwIChIMy4zIGNsdXN0ZXIpIOOBrue1kOaenOOCkkdPCgoyMDIwLjQuMjEsIDcuMTfkv67mraMgdmVyCgpgYGB7ciBHTyBwYXJ0MSBMb2FkIGxpc3QgSDNwMyBjbHVzdGVyfQojMjAyMDA0MjHkv67mraMgdmVyCiMyMDE5MTIwNuS/ruatoyB2ZXIKCiN6X2hlYXRfbGFiZWxfb3JkZXJfY2x1c3RlcjYgPC0gel9oZWF0X2xhYmVsX29yZGVyX2NsdXN0ZXIgJT4lIGRwbHlyOjpzZWxlY3QoZXh0X2dlbmUsaGVhdG1hcF9vcmRlcixObyxjbHVzdGVyXzYpICU+JSBtdXRhdGUoaGVhdG1hcF9vcmRlcj1hcy5pbnRlZ2VyKGhlYXRtYXBfb3JkZXIpLE5vPWFzLmludGVnZXIoTm8pLGNsdXN0ZXJfNj1hcy5pbnRlZ2VyKGNsdXN0ZXJfNikpJT4lIGFycmFuZ2UoaGVhdG1hcF9vcmRlcikgJT4lIGxlZnRfam9pbiggZHBseXI6OnNlbGVjdCh6X3RpbWVkZWdfcyxlbnNfZ2VuZSxleHRfZ2VuZSxiaW90eXBlLGNocikpCiNfX19fX19fX19fX19fIwoKIyMgel9oZWF0X2xhYmVsX29yZGVyX2NsdXN0ZXIg44Gr44Kv44Op44K544K/44O855Wq5Y+344GM5YWl44Gj44Gm44GE44KLCgp0YWJsZV9kZWdjbHVzdGVyIDwtIHJycmVzX2FsbEgzcDMgJT4lIGZpbHRlcighaXMubmEoY2x1c3RlcikpICU+JSBhcnJhbmdlKGNsdXN0ZXIsIGVuc19nZW5lKSAlPiUgdW5pcXVlKCkgJT4lIGZpbHRlcighaXMubmEoZW5zX2dlbmUpKQpkZWdjbHVzZ2VuZSA8LSB0YWJsZV9kZWdjbHVzdGVyICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgc3VtbWFyaXNlKHNpemU9bigpKSAlPiUgbXV0YXRlKGNsdXN0ZXI9cm93X251bWJlcigpKQoKdGFibGVfZGVnY2x1c3RlciA8LSB0YWJsZV9kZWdjbHVzdGVyICU+JSBsZWZ0X2pvaW4oZGVnY2x1c2dlbmUgJT4lIGRwbHlyOjpzZWxlY3QoY2x1c3RlcikpICU+JSBhcnJhbmdlKGNsdXN0ZXIsZW5zX2dlbmUpCgpkZWdjbHVzZ2VuZQojIyMjIyBGRFIgc2V0dGluZyAjIyMjIyMKZ29mZHIgPC0gMC4xCgojY2x1c3Rlcl9udW0gPC0gNgpjbHVzdGVyX251bSA8LSBucm93KGRlZ2NsdXNnZW5lKQoKYGBgCgpgYGB7ciBnbyBwYXJ0MiBjbHVzdGVyUHJvZmlsZSBIM3AzIGNsdXN0ZXJ9CiMgMjAxOTEyMDbkv67mraMKCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KG9yZy5NbS5lZy5kYikKCmZvbGRlcl9wYXRoIDwtICIuL0gzcDNhbGxjbHVzdGVyL2NsdXN0ZXJQcm9maWxlLyIKCiMtLS0tLS0tLS0tLS0tIwpmaWxlX3BhdGggPC0gcGFzdGUoZm9sZGVyX3BhdGgsICJHT19uZXdjbHVzdGVyX0JQZmRyMHAxX2dlbmVyYXRpbyIsc2VwPSIiKQpmaWxlbmFtZV9jc3YgPC0gZmlsZV9wYXRoCgpmaWxlX3BhdGggPC0gcGFzdGUoZm9sZGVyX3BhdGgsICJHT19uZXdjbHVzdGVyX0JQZmRyMHAxX2dlbmVyYXRpb19jbHVzdGVyIixzZXA9IiIpCmZpbGVuYW1lX2xpc3QgPC0gZmlsZV9wYXRoCgpwcmludChmaWxlbmFtZV9saXN0KQpwcmludChmaWxlbmFtZV9jc3YpCgoj5L6LIGZpbGVuYW1lX2xpc3QgPC0gIi4vTFJUL2NsdXN0ZXJQcm9maWxlL0gzbW0xOEtPX21vdXNlQ1RYX0JSQjA0MzhfZGF5NV8yZ3VuZmRyMHAyX2ttZWFuc19CUGZkcjBwMV9nZW5lcmF0aW9fY2x1c3RlciIKI+S+iyBmaWxlbmFtZV9jc3YgPC0gIi4vTFJUL2NsdXN0ZXJQcm9maWxlL0gzbW0xOEtPX21vdXNlQ1RYX0JSQjA0MzhfZGF5NV8yZ3VuZmRyMHAyX2tlbWFuc19CUGZkcjBwMV9nZW5lcmF0aW8iCiMtLS0tLS0tLS0tLS0tIwoKY2x1c3Rlcl9saXN0IDwtIGFzLmxpc3QoTkEpICPliJ3mnJ/ljJYKCmZvciAoaSBpbiAxOmNsdXN0ZXJfbnVtKSB7CiAgIHByZV9saXN0IDwtIGFzLmxpc3QoTkEpCiAgIHByZV9saXN0IDwtIHRhYmxlX2RlZ2NsdXN0ZXIgJT4lIGZpbHRlcihjbHVzdGVyPT1hcy5pbnRlZ2VyKGkpKSAlPiUgZHBseXI6OnNlbGVjdChlbnNfZ2VuZSkgJT4lIGFzLmxpc3QoKQogICBuYW1lcyhwcmVfbGlzdCkgPC0gcGFzdGUoIkVOU0VNQkwiLGFzLmNoYXJhY3RlcihpKSxzZXA9Il8iKQogCiAgIGlmIChpID09IDEpIHsgCiAgICAgY2x1c3Rlcl9saXN0IDwtIHByZV9saXN0CiAgIH0gCiAgIGVsc2UgY2x1c3Rlcl9saXN0IDwtIGMoY2x1c3Rlcl9saXN0LCBwcmVfbGlzdCkgCn0KCgpmb3IgKGkgaW4gMTpjbHVzdGVyX251bSkgewogICBwcmludChwYXN0ZShpLCBjbHVzdGVyX2xpc3RbW2ldXSAlPiUgdGliYmxlOjplbmZyYW1lKG5hbWUgPSBOVUxMKSAlPiUgbnJvdygpLCBzZXA9IiwgIikpCiAgCiAgIHByZV9lZ29fQlAgPC0gZW5yaWNoR08oZ2VuZSA9IGNsdXN0ZXJfbGlzdFtbaV1dLAogICAgICAgICAgICAgICAgIE9yZ0RiID0gIm9yZy5NbS5lZy5kYiIsCiAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICdFTlNFTUJMJywKICAgICAgICAgICAgICAgICBvbnQgPSAiQlAiLAogICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiLAogICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiAgPSBnb2ZkciwgcXZhbHVlQ3V0b2ZmICA9IDEuMCkgCiAgIAogICAjMjAxOTEyMTHkv67mraMgIHB2YWx1ZUN1dG9mZiAgPSBmZHIKICAgCiAgICMjIHB2YWx1ZSA8IHF2YWx1ZSA8IHAuYWRqdXN0ICMjCiAgICMgcXZhbHVlQ3V0b2ZmICA9IDAuMyAgcXZhbHVlQ3V0b2ZmICA9IDAuMiAsIHF2YWx1ZUN1dG9mZiAgPSAxLjAKCiAgICNpZiAoaSA9PSAxKSB7IAogICMgICB0YWJsZV9lZ29fQlAgPC0gZGF0YS5mcmFtZShwcmVfZWdvX0JQKSAlPiUgbXV0YXRlKGNsdXN0ZXI9YXMuaW50ZWdlcihpKSkKICAjICAgIyDjg6rjgrnjg4jlnovjgYvjgonjg4fjg7zjgr/jg5Xjg6zjg7zjg6DjgbjlpInmj5sKICAgI30gCiAgICNlbHNlIHRhYmxlX2Vnb19CUCA8LSB0YWJsZV9lZ29fQlAgJT4lIGJpbmRfcm93cyhkYXRhLmZyYW1lKHByZV9lZ29fQlApICU+JSBtdXRhdGUoY2x1c3Rlcj1hcy5pbnRlZ2VyKGkpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICBpZiAoaSA9PSAxKSB7IAogICAgIHRhYmxlX2Vnb19CUCA8LSBkYXRhLmZyYW1lKHByZV9lZ29fQlApICU+JSBtdXRhdGUoY2x1c3Rlcj1wYXN0ZSgiY2x1c3RlciIsYXMuY2hhcmFjdGVyKGkpLHNlcD0iIikpICAjIOODquOCueODiOWei+OBi+OCieODh+ODvOOCv+ODleODrOODvOODoOOBuOWkieaPmwogICB9IAogICBlbHNlIHRhYmxlX2Vnb19CUCA8LSB0YWJsZV9lZ29fQlAgJT4lIGJpbmRfcm93cyhkYXRhLmZyYW1lKHByZV9lZ29fQlApICU+JSBtdXRhdGUoY2x1c3Rlcj1wYXN0ZSgiY2x1c3RlciIsYXMuY2hhcmFjdGVyKGkpLHNlcD0iIikpKQogICAKICAgIy0tLS0gcGxvdCAtLS0jCiAgIEJQcGxvdCA8LSBkb3RwbG90KHByZV9lZ29fQlAsIHNob3dDYXRlZ29yeT0zMCwgb3JkZXJCeSA9ICJDb3VudCIpICNjbHVzdGVyUHJvZmlsZSDjga7mqZ/og73jgaflm7PjgpLmj4/jgY8oMTkxMTA25L+u5q2jKSB3cm9uZyBvcmRlckJ5IHBhcmFtZXRlcjsgc2V0IHRvIGRlZmF1bHQgYG9yZGVyQnkgPSAieCJgCiAgIHByaW50KEJQcGxvdCkKICAgZ2dzYXZlKEJQcGxvdCxmaWxlPXBhc3RlKGZpbGVuYW1lX2xpc3QsYXMuY2hhcmFjdGVyKGkpLCIucG5nIixzZXA9IiIpLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMiwgZHBpID0gMTIwKQogICBnZ3NhdmUoQlBwbG90LGZpbGU9cGFzdGUoZmlsZW5hbWVfbGlzdCxhcy5jaGFyYWN0ZXIoaSksIi5wZGYiLHNlcD0iIiksIHdpZHRoID0gMTIsIGhlaWdodCA9IDEyLCBkcGkgPSAxMjApCn0KCnByaW50KHRhYmxlX2Vnb19CUCAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHN1bW1hcml6ZSgpKQoKIy0tLS0tLSMKIyDjg4fjg7zjgr/jga90YWJsZV9lZ29fQlDjgavjgIIKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jCiMg44OG44O844OW44Or44KS5L+d5a2YCiMgdGFibGVfZWdvX0JQXzN0M19MUlQyIDwtIHRhYmxlX2Vnb19CUAojCnRhYmxlX2Vnb19CUDEgPC0gdGFibGVfZWdvX0JQICU+JSBtdXRhdGUoY2x1c3Rlcj1mYWN0b3IoY2x1c3RlcixjKCJjbHVzdGVyMSIsImNsdXN0ZXIyIiwiY2x1c3RlcjMiLCJjbHVzdGVyNCIsImNsdXN0ZXI1IiwiY2x1c3RlcjYiKSkpICU+JSBhcnJhbmdlKGNsdXN0ZXIsZGVzYyhDb3VudCkpICMxOTExMDYoMjAwNDE1KQoKI3RhYmxlX2Vnb19CUDEgPC0gdGFibGVfZWdvX0JQICU+JSBhcnJhbmdlKGNsdXN0ZXIsZGVzYyhDb3VudCkpICAlPiUgbGVmdF9qb2luKGRwbHlyOjpzZWxlY3QoZGVnY2x1c2dlbmUsIGNsdXN0ZXIpKSAjMTkxMTA2KDIwMDQxNSkKCnJlYWRyOjp3cml0ZV9jc3YodGFibGVfZWdvX0JQMSxwYXN0ZShmaWxlbmFtZV9jc3YsIi5jc3YiLHNlcD0iIikpCgpgYGAKCmBgYHtyIGdvIHBhcnQyLTIgY2x1c3RlclByb2ZpbGUgSDNwMyBjbHVzdGVyfQoKcHJpbnQodGFibGVfZWdvX0JQICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgc3VtbWFyaXplKGNsdXN0ZXJfM3QzRG94X251bSA9IGRwbHlyOjpuKCkpKQoKIyDlhYjjga7jg4bjg7zjg5bjg6vjga5nZW5lSUTjgpJnZW5lIG5hbWXjgavnva7mj5vjgZnjgovjgIIoMjAxOTEwMjUpCgp0YWJsZWdvIDwtIHRhYmxlX2Vnb19CUDEgJT4lIG11dGF0ZShnZW5lX25hbWU9Z2VuZUlEKSAlPiUgZHBseXI6OnNlbGVjdCgtKHF2YWx1ZSkpCgpmb3IgKGkgaW4gMTpucm93KHRhYmxlX2RlZ2NsdXN0ZXIpKSB7CiAgdGFibGVnbyA8LSB0YWJsZWdvICU+JSBtdXRhdGUoZ2VuZV9uYW1lPWdzdWIoZ2VuZV9uYW1lLCBwYXR0ZXJuPXRhYmxlX2RlZ2NsdXN0ZXIkZW5zX2dlbmVbaV0sIHJlcGxhY2VtZW50PXRhYmxlX2RlZ2NsdXN0ZXIkZXh0X2dlbmVbaV0sIGlnbm9yZS5jYXNlID0gVFJVRSkpCn0KCiNwcmludCh0YWJsZWdvKQoKI3JlYWRyOjp3cml0ZV9jc3YodGFibGVnbyxwYXN0ZShmaWxlbmFtZV9jc3YsIl9nZW5lbmFtZS5jc3YiLHNlcD0iIikpCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwoKCmBgYAoKCmBgYHtyIEdPIHNhdmV9CgpyZWFkcjo6d3JpdGVfY3N2KHRhYmxlZ28scGFzdGUoZmlsZW5hbWVfY3N2LCJfZ2VuZW5hbWUuY3N2IixzZXA9IiIpKQoKYGBgCgoKCi0tLS0tLS0tLS0tLS0tLQpgYGB7ciBjaHJvbVZBUn0KCmxpYnJhcnkoY2hyb21WQVIpCmxpYnJhcnkobW90aWZtYXRjaHIpCmxpYnJhcnkoU3VtbWFyaXplZEV4cGVyaW1lbnQpCmxpYnJhcnkoTWF0cml4KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoQmlvY1BhcmFsbGVsKQpsaWJyYXJ5KEJTZ2Vub21lLk1tdXNjdWx1cy5VQ1NDLm1tMTApCgpsaXN0X3Bsb3RhbGxGQ2N1dG9mZl9IM3AzY2x1czMgPC0gZHBseXI6OnNlbGVjdChwbG90X2FsbF9GQ19jdXRvZmZfSDNwM2NsdXMzLCBlbnNfZ2VuZSwgZXh0X2dlbmUsIGJpb3R5cGUsIGNociwgSDNwM2NsdXN0ZXIsIEJSQkRFR2NsdXN0ZXIpICU+JSB1bmlxdWUoKQoKVFNTcmVnaW9uX0gzcDNjbHVzMyA8LSAgbWF0b21lMF9zICU+JSB1bmdyb3VwICU+JSBkcGx5cjo6c2VsZWN0KFRTU3N0YXJ0LFRTU2VuZCxlbnNfZ2VuZSxzY29yZSxzdHJhbmQsVFNTLFN0YXJ0LEVuZCxwb3NpdGlvbikgJT4lIGZpbHRlcihlbnNfZ2VuZSAlaW4lIGxpc3RfcGxvdGFsbEZDY3V0b2ZmX0gzcDNjbHVzMyRlbnNfZ2VuZSkgJT4lIHVuZ3JvdXAoKSAlPiUgbGVmdF9qb2luKGxpc3RfcGxvdGFsbEZDY3V0b2ZmX0gzcDNjbHVzMykKCiNUU1NQTTEwa2JfSDNwM2NsdXMzIDwtIFRTU3JlZ2lvbl9IM3AzY2x1czMgJT4lIG11dGF0ZShUU1NfTTEwa2I9VFNTLTEwMDAwLFRTU19QMTBrYj1UU1MrMTAwMDApICU+JSBkcGx5cjo6c2VsZWN0KGNocixUU1NfTTEwa2IsVFNTX1AxMGtiLGVuc19nZW5lLHNjb3JlLHN0cmFuZCxUU1MsICBTdGFydCwgICAgRW5kLCBwb3NpdGlvbiwgZXh0X2dlbmUsIGJpb3R5cGUsIEgzcDNjbHVzdGVyLCBCUkJERUdjbHVzdGVyKQoKVFNTUE0xMGtiX0gzcDNjbHVzMyA8LSBUU1NyZWdpb25fSDNwM2NsdXMzICU+JSBkcGx5cjo6c2VsZWN0KGNocixUU1MsZW5zX2dlbmUsIGV4dF9nZW5lLGJpb3R5cGUsIHNjb3JlLCBzdHJhbmQsIEgzcDNjbHVzdGVyLCBCUkJERUdjbHVzdGVyKSAlPiUgbXV0YXRlKHN0YXJ0PVRTUy0xMDAwMCxlbmQ9VFNTKzEwMDAwKSAlPiUgZHBseXI6OnNlbGVjdChjaHIsc3RhcnQsZW5kLGVuc19nZW5lLCBzY29yZSwgc3RyYW5kLFRTUywgZXh0X2dlbmUsYmlvdHlwZSwgIEgzcDNjbHVzdGVyLCBCUkJERUdjbHVzdGVyKSAlPiUgZmlsdGVyKEJSQkRFR2NsdXN0ZXI9PSIzIikKCgpUU1NQTTEwa2JfSDNwM2NsdXMzX0dSIDwtIG1ha2VHUmFuZ2VzRnJvbURhdGFGcmFtZShUU1NQTTEwa2JfSDNwM2NsdXMzLCBrZWVwLmV4dHJhLmNvbHVtbnMgPSBUUlVFKQoKc2VxbGV2ZWxzU3R5bGUoVFNTUE0xMGtiX0gzcDNjbHVzM19HUikgPC0gIlVDU0MiCgojIyMjIwoKcGVha2ZpbGUgPC0gIi4vTW90aWYvVFNTUE0xMGtiX0gzcDNjbHVzMy5jc3YiCnByaW50KHBlYWtmaWxlKQpyZWFkcjo6d3JpdGVfY3N2KFRTU1BNMTBrYl9IM3AzY2x1czMscGVha2ZpbGUpCmhlYWQoVFNTUE0xMGtiX0gzcDNjbHVzMykKbnJvdyhUU1NQTTEwa2JfSDNwM2NsdXMzKQoKCmBgYAoKCmBgYHtyIHJlYWQgZGVmdGFibGV9CgpkZWZfYmFtX3BhdGggPC0gIi9ob21lL2d1ZXN0QS9vNzA1NzhhL2FrdXdha2Fkby9rdXdha2Fkby9DaElMU2VxMi9Lb21hdHN1XzNUM19FR0ZQX0gzbW0xOF9Eb3hfY2hJbF8wMTExTk9WQXNlcS9DaHJvbVZBUi9DaHJvbVZBUl9DaElML0gzSzI3YWNfSDNLMjdhY3BlYWsvZGVmdGFibGVfQ2hyb21WQVJfQ2hJTDAxMTAwMTExXzIwMjAwNTAxXzNUM19FR0ZQMThfVUlfRG94TWludXNfSDNwM0syN2FjSzRLbWUzMjdtZTMudHh0IgoKZGVmX0gzSzI3YWNfYmFtIDwtICByZWFkcjo6cmVhZF90c3YoZmlsZSA9ZGVmX2JhbV9wYXRoKSAlPiUgZmlsdGVyKHNlcT09IkgzSzI3YWMiKQoKCmJhbWZpbGVzIDwtIGRlZl9IM0syN2FjX2JhbSRmaWxlICNiYW1maWxlcyA8LSBkZWZfYmFtJHBlYWtjYWxsX2JhbQoKCmZyYWdtZW50X2NvdW50cyA8LSBnZXRDb3VudHMoZGVmX0gzSzI3YWNfYmFtJGZpbGUsIFRTU1BNMTBrYl9IM3AzY2x1czNfR1IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSAgRkFMU0UsICAjIENoSUzjga/jg5rjgqLjgafjga/jgarjgYTjgIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnlfcmcgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGEgPSBEYXRhRnJhbWUoQ2VsbF9UeXBlID0gZGVmX0gzSzI3YWNfYmFtJGdyb3VwLHNhbXBsZV9uYW1lID0gZGVmX0gzSzI3YWNfYmFtJHNhbXBsZSkpCgoKYGBgCgpgYGB7ciBmcmFnbWVudCBjb3VudH0KbGVuZ3RoKGZyYWdtZW50X2NvdW50cykKCnByaW50KCItLS0tIGZyYWdtZW50X2NvdW50cyAtLS0tIikKCnNsb3QoZnJhZ21lbnRfY291bnRzLCAicm93UmFuZ2VzIikgI2ZyYWdtZW50X2NvdW50cyBAcm93UmFuZ2VzCgpzbG90KGZyYWdtZW50X2NvdW50cywgImNvbERhdGEiKQpzbG90KGZyYWdtZW50X2NvdW50cywgIk5BTUVTIikKc2xvdChmcmFnbWVudF9jb3VudHMsICJtZXRhZGF0YSIpCnNsb3QoZnJhZ21lbnRfY291bnRzLCAiZWxlbWVudE1ldGFkYXRhIikKc2xvdChmcmFnbWVudF9jb3VudHMsICJhc3NheXMiKQoKCnByaW50KCItLS0tLS0tLS0gc2F2ZSAtLS0tLS0tLS0tLS0tLS0tIikKCiMtLSBzYXZlIGZyYWdtZW50IGNvdW50IC0tLS0jCiMtLS0tLS0tLSMKdHlwZV9kZXB0aCA8LSBzbG90KGZyYWdtZW50X2NvdW50cywgImNvbERhdGEiKSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAjIOevhOWbsgpmZmZpbGUgPC0gc3ViKCIuY3N2IiwiX3R5cGVkZXB0aC5jc3YiLHBlYWtmaWxlKQpwcmludChmZmZpbGUpCnR5cGVfZGVwdGggJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmZmaWxlKQojLS0tLS0tLS0jCmZfY19yYW5nZSA8LSBmcmFnbWVudF9jb3VudHMgQHJvd1JhbmdlcyAgJT4lIGFzLmRhdGEuZnJhbWUoKSAjIOevhOWbsgpmY19yYW5nZSA8LSBmX2NfcmFuZ2UgJT4lIG11dGF0ZShzZXFuYW1lczE9c2VxbmFtZXMsc3RhcnQxPXN0YXJ0LGVuZDE9ZW5kKSAlPiUgdW5pdGUoc3RlbixjKHN0YXJ0MSxlbmQxKSxzZXA9Ii0iKSAlPiUgdW5pdGUocmFuZ2UsYyhzZXFuYW1lczEsc3Rlbiksc2VwPSI6IikKCmZfY19jb3VudCA8LSBmcmFnbWVudF9jb3VudHMgQGFzc2F5cyBAZGF0YSRjb3VudHMgJT4lIGFzLm1hdHJpeCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgICMg44Kr44Km44Oz44OICiMtLS0jCmZfY19yYW5nZV9jb3VudCA8LSBjYmluZChmY19yYW5nZSwgZl9jX2NvdW50KQpucm93KGZfY19yYW5nZV9jb3VudCkKCmZmZmlsZSA8LSBzdWIoIi5jc3YiLCJfZnJhZ2NvdW50cy5jc3YiLHBlYWtmaWxlKQpwcmludChmZmZpbGUpCmZfY19yYW5nZV9jb3VudCAlPiUgcmVhZHI6OndyaXRlX2NzdihmZmZpbGUpCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jCgoKYGBgCgpgYGB7ciBmcmFnbWVudCBjb3VudCBiaWFzfQoKcmVnaXN0ZXIoU2VyaWFsUGFyYW0oKSkKZnJhZ21lbnRfY291bnRzX2JpYXMgPC0gYWRkR0NCaWFzKGZyYWdtZW50X2NvdW50cywgZ2Vub21lID0gQlNnZW5vbWUuTW11c2N1bHVzLlVDU0MubW0xMCkgI+OBk+OBk+OBp+OBk+OBkeOBquOBhOOCiOOBhuOBq+OAgUNocuOBr+eiuuWumuOBleOCjOOBpuOBhOOCi+OCguOBruOBq+ioreWumuOAggoKIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIwpsZW5ndGgoZnJhZ21lbnRfY291bnRzX2JpYXMpCnByaW50KCItLS0tIGZyYWdtZW50X2NvdW50c19iaWFzIC0tLS0iKQpwcmludCgiPT0gcm93UmFuZ2VzID09IikKc2xvdChmcmFnbWVudF9jb3VudHNfYmlhcywgInJvd1JhbmdlcyIpCnByaW50KCI9PSBjb2xEYXRhID09IikKc2xvdChmcmFnbWVudF9jb3VudHNfYmlhcywgImNvbERhdGEiKQpwcmludCgiPT0gTkFNRVMgPT0iKQpzbG90KGZyYWdtZW50X2NvdW50c19iaWFzLCAiTkFNRVMiKQpwcmludCgiPT0gbWV0YWRhdGEgPT0iKQpzbG90KGZyYWdtZW50X2NvdW50c19iaWFzLCAibWV0YWRhdGEiKQpwcmludCgiPT0gZWxlbWVudE1ldGFkYXRhID09IikKc2xvdChmcmFnbWVudF9jb3VudHNfYmlhcywgImVsZW1lbnRNZXRhZGF0YSIpCnByaW50KCI9PSBhc3NheXMgPT0iKQpzbG90KGZyYWdtZW50X2NvdW50c19iaWFzLCAiYXNzYXlzIikKCnByaW50KCItLS0tLS0tLS0gc2F2ZSAtLS0tLS0tLS0tLS0tLS0tIikKCiMtLSBzYXZlIGZyYWdtZW50IGNvdW50IGJpYXMtLS0tIwpmX2NfcmFuZ2VfYmlhcyA8LSBmcmFnbWVudF9jb3VudHNfYmlhcyBAcm93UmFuZ2VzICAlPiUgYXMuZGF0YS5mcmFtZSgpICMg56+E5ZuyCmZjX3JhbmdlX2JpYXMgPC0gZl9jX3JhbmdlX2JpYXMgJT4lIG11dGF0ZShzZXFuYW1lczE9c2VxbmFtZXMsc3RhcnQxPXN0YXJ0LGVuZDE9ZW5kKSAlPiUgdW5pdGUoc3RlbixjKHN0YXJ0MSxlbmQxKSxzZXA9Ii0iKSAlPiUgdW5pdGUocmFuZ2UsYyhzZXFuYW1lczEsc3Rlbiksc2VwPSI6IikKCmZfY19jb3VudF9iaWFzIDwtIGZyYWdtZW50X2NvdW50c19iaWFzIEBhc3NheXMgQGRhdGEkY291bnRzICU+JSBhcy5tYXRyaXgoKSAlPiUgYXMuZGF0YS5mcmFtZSgpICAjIOOCq+OCpuODs+ODiAojLS0tIwpmX2NfcmFuZ2VfY291bnRfYmlhcyA8LSBjYmluZChmY19yYW5nZV9iaWFzLCBmX2NfY291bnRfYmlhcykKbnJvdyhmX2NfcmFuZ2VfY291bnRfYmlhcykKCmZmZmlsZSA8LSBzdWIoIi5jc3YiLCJfZnJhZ2NvdW50c19iaWFzLmNzdiIscGVha2ZpbGUpCnByaW50KGZmZmlsZSkKZl9jX3JhbmdlX2NvdW50X2JpYXMgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmZmaWxlKQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwoKYGBgCgpgYGB7ciBjb3VudCBmaWx0ZXJlZCAxfQojY291bnRzX2ZpbHRlcmVkIDwtIGZpbHRlclNhbXBsZXMoZnJhZ21lbnRfY291bnRzX2JpYXMsIG1pbl9kZXB0aCA9IDE1MDAsIG1pbl9pbl9wZWFrcyA9IDAuMTUsIHNoaW55ID0gRkFMU0UpCmNvdW50c19maWx0ZXJlZF9wcmUgPC0gZmlsdGVyU2FtcGxlcyhmcmFnbWVudF9jb3VudHNfYmlhcywgc2hpbnkgPSBGQUxTRSkKCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIwojIElmIHVuc3BlY2lmaWVkLCBtaW5faW5fcGVha3MgYW5kIG1pbl9kZXB0aCBjdXRvZmZzIHdpbGwgYmUgZXN0aW1hdGVkIGJhc2VkIG9uIGRhdGEuIG1pbl9pbl9wZWFrcyBpcyBzZXQgdG8gMC41IHRpbWVzIHRoZSBtZWRpYW4gcHJvcG9ydGlvbiBvZiBmcmFnbWVudHMgaW4gcGVha3MuIG1pbl9kZXB0aCBpcyBzZXQgdG8gdGhlIG1heGltdW0gb2YgNTAwIG9yIDEwIG1lZGlhbiBsaWJyYXJ5IHNpemUuCiMKIyBtaW5faW5fcGVha3M6IG1pbmltdW0gZnJhY3Rpb24gb2Ygc2FtcGxlcyB3aXRoaW4gcGVha3MKIyBtaW5fZGVwdGg6CW1pbmltdW0gbGlicmFyeSBzaXplCiMgc2hpbnk6CW1ha2Ugc2hpbnkgZ2FkZ2V0PwojIGl4X3JldHVybjoJcmV0dXJuIGluZGljZXMgb2Ygc2FtcGxlIHRvIGtlZXAgaW5zdGVhZCBvZiBzdWJzZXR0ZWQgY291bnRzIG9iamVjdAojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMKCmxlbmd0aChjb3VudHNfZmlsdGVyZWRfcHJlKQpwcmludCgiLS0tLSBjb3VudHNfZmlsdGVyZWQgKHByZSkgLS0tLSIpCnByaW50KCI9PSByb3dSYW5nZXMgPT0iKQpzbG90KGNvdW50c19maWx0ZXJlZF9wcmUsICJyb3dSYW5nZXMiKQpwcmludCgiPT0gY29sRGF0YSA9PSIpCnNsb3QoY291bnRzX2ZpbHRlcmVkX3ByZSwgImNvbERhdGEiKQpwcmludCgiPT0gTkFNRVMgPT0iKQpzbG90KGNvdW50c19maWx0ZXJlZF9wcmUsICJOQU1FUyIpCnByaW50KCI9PSBtZXRhZGF0YSA9PSIpCnNsb3QoY291bnRzX2ZpbHRlcmVkX3ByZSwgIm1ldGFkYXRhIikKcHJpbnQoIj09IGVsZW1lbnRNZXRhZGF0YSA9PSIpCnNsb3QoY291bnRzX2ZpbHRlcmVkX3ByZSwgImVsZW1lbnRNZXRhZGF0YSIpCnByaW50KCI9PSBhc3NheXMgPT0iKQpzbG90KGNvdW50c19maWx0ZXJlZF9wcmUsICJhc3NheXMiKQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpCgpgYGAKCmBgYHtyIGNvdW50IGZpbHRlcmVkIDJ9CmNvdW50c19maWx0ZXJlZCA8LSBmaWx0ZXJQZWFrcyhjb3VudHNfZmlsdGVyZWRfcHJlLG5vbl9vdmVybGFwcGluZz1UUlVFKQoKIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjCiMgaWYgbm9uX292ZXJsYXBwaW5nIGlzIHNldCB0byB0cnVlLCB3aGVuIHBlYWtzIG92ZXJsYXAgdGhlIG92ZXJsYXBwaW5nIHBlYWsgd2l0aCBsb3dlciBjb3VudHMgaXMgcmVtb3ZlZAojCiMgbWluX2ZyYWdtZW50c19wZXJfcGVhazoJbWluaW11bSBudW1iZXIgb2YgZnJhZ21pbnRzIGluIHBlYWtzIGFjcm9zcyBhbGwgc2FtcGxlcwojIG5vbl9vdmVybGFwcGluZzoJcmVkdWNlIHBlYWsgc2V0IHRvIG5vbi1vdmVybGFwcGluZyBwZWFrcywgc2VlIGRldGFpbHMKIyBpeF9yZXR1cm46CXJldHVybiBpbmRpY2VzIG9mIHBlYWtzIHRvIGtlZXAgaW5zdGVhZCBvZiBzdWJzZXR0ZWQgY291bnRzIG9iamVjdAojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMKCmxlbmd0aChjb3VudHNfZmlsdGVyZWQpCnByaW50KCItLS0tIGNvdW50c19maWx0ZXJlZCAtLS0tIikKc2xvdChjb3VudHNfZmlsdGVyZWQsICJyb3dSYW5nZXMiKQpzbG90KGNvdW50c19maWx0ZXJlZCwgImNvbERhdGEiKQpzbG90KGNvdW50c19maWx0ZXJlZCwgIk5BTUVTIikKc2xvdChjb3VudHNfZmlsdGVyZWQsICJtZXRhZGF0YSIpCnNsb3QoY291bnRzX2ZpbHRlcmVkLCAiZWxlbWVudE1ldGFkYXRhIikKc2xvdChjb3VudHNfZmlsdGVyZWQsICJhc3NheXMiKQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpCgojLS0gc2F2ZSBjb3VudHNfZmlsdGVyZWQgLS0tLSMKZl9jX3JhbmdlX2NvdW50c2ZpbCA8LSBjb3VudHNfZmlsdGVyZWQgQHJvd1JhbmdlcyAgJT4lIGFzLmRhdGEuZnJhbWUoKSAjIOevhOWbsgpmY19yYW5nZV9jb3VudHNmaWwgPC0gZl9jX3JhbmdlX2NvdW50c2ZpbCAlPiUgbXV0YXRlKHNlcW5hbWVzMT1zZXFuYW1lcyxzdGFydDE9c3RhcnQsZW5kMT1lbmQpICU+JSB1bml0ZShzdGVuLGMoc3RhcnQxLGVuZDEpLHNlcD0iLSIpICU+JSB1bml0ZShyYW5nZSxjKHNlcW5hbWVzMSxzdGVuKSxzZXA9IjoiKQoKZl9jX2NvdW50X2NvdW50c2ZpbCA8LSBjb3VudHNfZmlsdGVyZWQgQGFzc2F5cyBAZGF0YSRjb3VudHMgJT4lIGFzLm1hdHJpeCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgICMg44Kr44Km44Oz44OICiMtLS0jCmZfY19yYW5nZV9jb3VudF9jb3VudHNmaWwgPC0gY2JpbmQoZmNfcmFuZ2VfY291bnRzZmlsLCBmX2NfY291bnRfY291bnRzZmlsKQpucm93KGZfY19yYW5nZV9jb3VudF9jb3VudHNmaWwpCgpmZmZpbGUgPC0gc3ViKCIuY3N2IiwiX2NvdW50c2ZpbHRlci5jc3YiLHBlYWtmaWxlKQpwcmludChmZmZpbGUpCmZfY19yYW5nZV9jb3VudF9jb3VudHNmaWwgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmZmaWxlKQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwoKYGBgCgpSYXcgZGV2aWF0aW9ucyBmb3IgYmFja2dyb3VuZCBwZWFrcwomIEJpYXMgY29ycmVjdGVkIGRldmlhdGlvbnMgYW5kIFotc2NvcmVzCgpgYGB7ciBtb3RpZiBjb3VudHNfZmlsdGVyZWQgZGV2fQoKbGVuZ3RoKGNvdW50c19maWx0ZXJlZCkKCm1vdGlmcyA8LSBjaHJvbVZBUjo6Z2V0SmFzcGFyTW90aWZzKHNwZWNpZXMgPSAiTXVzIG11c2N1bHVzIiwgY29sbGVjdGlvbiA9ICJDT1JFIikgI09LCm1vdGlmX2l4IDwtIG1hdGNoTW90aWZzKG1vdGlmcywgY291bnRzX2ZpbHRlcmVkLCBnZW5vbWUgPSBCU2dlbm9tZS5NbXVzY3VsdXMuVUNTQy5tbTEwKQojbW90aWZNYXRjaGVzKG1vdGlmX2l4KSAjIEV4dHJhY3QgbWF0Y2hlcyBtYXRyaXggZnJvbSBTdW1tYXJpemVkRXhwZXJpbWVudCByZXN1bHQKZGV2IDwtIGNvbXB1dGVEZXZpYXRpb25zKG9iamVjdCA9IGNvdW50c19maWx0ZXJlZCwgYW5ub3RhdGlvbnMgPSBtb3RpZl9peCkKCgpgYGAKCkNocm9tVkFS44GnIOOCqOODqeODvOOBruOBn+OCgeOBk+OBk+OBp+e1guS6higyMDIwMDgxOSkKCgojIyMjIGRpZmZlcmVudGlhbERldgoKKDIwMjAwNjE36L+95YqgKQpodHRwczovL2dyZWVubGVhZmxhYi5naXRodWIuaW8vY2hyb21WQVIvcmVmZXJlbmNlL2RpZmZlcmVudGlhbERldmlhdGlvbnMuaHRtbAoKZGF0YShtaW5pX2RldiwgcGFja2FnZSA9ICJjaHJvbVZBUiIpCmRpZmRldiA8LSBkaWZmZXJlbnRpYWxEZXZpYXRpb25zKG1pbmlfZGV2LCAiQ2VsbF9UeXBlIikKZGlmZmVyZW50aWFsRGV2aWF0aW9ucyhvYmplY3QsIGdyb3VwcywgYWx0ZXJuYXRpdmUgPSBjKCJ0d28uc2lkZWQiLCAibGVzcyIsImdyZWF0ZXIiKSwgcGFyYW1ldHJpYyA9IFRSVUUpCmRldkBjb2xEYXRhCgpgYGB7ciBkaWZmZXJlbnRpYWxEZXZ9CmRpZmRldiA8LSBkaWZmZXJlbnRpYWxEZXZpYXRpb25zKGRldiwgIkNlbGxfVHlwZSIsIGFsdGVybmF0aXZlID0gYygidHdvLnNpZGVkIikpCiNkaWZkZXYgPC0gZGlmZmVyZW50aWFsRGV2aWF0aW9ucyhkZXYsICJDZWxsX1R5cGUiLCBwYXJhbWV0cmljID0gVFJVRSkKZGlmZGV2X3RhYmxlIDwtIGRpZmRldiAgJT4lIGFzX3RpYmJsZShyb3duYW1lcyA9ICJtb3RpZl9JRCIpICAlPiUgbGVmdF9qb2luKG1vdGlmX2lkKQpkaWZkZXZfdGFibGVfc2VsZWN0IDwtIGRpZmRldl90YWJsZSAlPiUgZmlsdGVyKHBfdmFsdWVfYWRqdXN0ZWQ8MC4wNSkgCgojLS0gc2F2ZSBkaWZkZXZfdGFibGUgd2l0aCBtb3RpZm5hbWUgLS0tLSMKZmZmaWxlIDwtIHN1YigiLmJlZCIsIl9kaWZkZXZfdGFibGVfYWxsLmNzdiIscGVha2ZpbGUpCnByaW50KGZmZmlsZSkKZGlmZGV2X3RhYmxlICU+JSByZWFkcjo6d3JpdGVfY3N2KGZmZmlsZSkKbnJvdyhkaWZkZXZfdGFibGUpCiMtLSBzYXZlIGRpZmRldl90YWJsZSB3aXRoIG1vdGlmbmFtZSAtLS0tIwpmZmZpbGUgPC0gc3ViKCIuYmVkIiwiX2RpZmRldl90YWJsZV9mZHIwcDAxLmNzdiIscGVha2ZpbGUpCnByaW50KGZmZmlsZSkKZGlmZGV2X3RhYmxlX3NlbGVjdCAlPiUgcmVhZHI6OndyaXRlX2NzdihmZmZpbGUpCm5yb3coZGlmZGV2X3RhYmxlX3NlbGVjdCkKIy0tLS0tIwoKZGlmZGV2X3RhYmxlX3NlbGVjdCAlPiUgZmlsdGVyKG1vdGlmX25hbWUgJWluJSBjKCJNeW9kMSIsIk15b2ciLCJUY2YxMiIsIlRjZjIxIiwiQXNjbDIiLCJGT1M6OkpVTiIsIk5mZTJsMiIsIkJhY2gxOjpNYWZrIiwiUlVOWDEiLCJNeWIiLCJCY2w2IiwiS2xmMTIiLCJLbGY0IiwiS2xmMSIsIkdhdGE0IiwiR2F0YTEiLCJSZngxIiwiU3B6MSIsIk15YyIsIkF0b2gxIikpCgojZGlmZGV2X1VJIDwtIGRpZmZlcmVudGlhbERldmlhdGlvbnMoZGV2LCBDZWxsX1R5cGUsIGFsdGVybmF0aXZlID0gYygidHdvLnNpZGVkIiwgICJEb3htaW51c19VSV9BVEFDIiwgIkRveHBsdXNfVUlfQVRBQyIpLCBwYXJhbWV0cmljID0gVFJVRSkKI2RpZmRldl9ENDggPC0gZGlmZmVyZW50aWFsRGV2aWF0aW9ucyhkZXYsICJDZWxsX1R5cGUiLCBhbHRlcm5hdGl2ZSA9IGMoInR3by5zaWRlZCIsICJEb3htaW51c19ENDhfQVRBQyIsICJEb3hwbHVzX0Q0OF9BVEFDIiksIHBhcmFtZXRyaWMgPSBUUlVFKQoKCmBgYAolPiUgZmlsdGVyKCFtb3RpZl9uYW1lICVpbiUgYygiTXlvZDEiLCJNeW9nIiwiVGNmMTIiLCJUY2YyMSIsIkFzY2wyIikpICAlPiUgZmlsdGVyKCFtb3RpZl9uYW1lICVpbiUgYygiRk9TOjpKVU4iLCJOZmUybDIiLCJCYWNoMTo6TWFmayIpKSAlPiUgZmlsdGVyKCFtb3RpZl9uYW1lICVpbiUgYygiUlVOWDEiLCJNeWIiKSkgICU+JSBmaWx0ZXIoIW1vdGlmX25hbWUgJWluJSBjKCJCY2w2IiwiS2xmMTIiLCJLbGY0IiwiS2xmMSIsIkdhdGE0IiwiR2F0YTEiLCJSZngxIiwiU3B6MSIsIk15YyIsIkF0b2gxIikpCgolPiUgZmlsdGVyKG1vdGlmX25hbWUgJWluJSBjKCJNeW9kMSIsIk15b2ciLCJUY2YxMiIsIlRjZjIxIiwiQXNjbDIiKSkgICU+JSBmaWx0ZXIobW90aWZfbmFtZSAlaW4lIGMoIkZPUzo6SlVOIiwiTmZlMmwyIiwiQmFjaDE6Ok1hZmsiKSkgJT4lIGZpbHRlcihtb3RpZl9uYW1lICVpbiUgYygiUlVOWDEiLCJNeWIiKSkgICU+JSBmaWx0ZXIobW90aWZfbmFtZSAlaW4lIGMoIkJjbDYiLCJLbGYxMiIsIktsZjQiLCJLbGYxIiwiR2F0YTQiLCJHYXRhMSIsIlJmeDEiLCJTcHoxIiwiTXljIiwiQXRvaDEiKSkKCgoKYGBge3Igc2F2ZTEgbW90aWYgZnJhZ21lbnRfY291bnRzX2JpYXMgZGV2fQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjCgpwcmludCgiLS0tLSBtb3RpZl9peCAtLS0tLS0tLS0tLS0tLS0tIikKbW90aWZfaWQgPC0gbW90aWZfaXggQGNvbERhdGEgJT4lIGFzX3RpYmJsZShyb3duYW1lcyA9ICJtb3RpZl9JRCIpICU+JSBkcGx5cjo6cmVuYW1lKG1vdGlmX25hbWU9bmFtZSkgI3JlbmFtZSBtb2RpZiAyMDIwMDYxNgoKcHJpbnQoIi0tIG1vdGlmTWF0Y2hlcyhtb3RpZl9peCkgLS0iKQojIyBtb3RpZk1hdGNoZXMg44GMIC4gb3IgfCDjgacg5YWl44Gj44Gm44GE44KLCm1vdGlmTV90YWJsZSA8LSBtb3RpZk1hdGNoZXMobW90aWZfaXgpICU+JSBhcy5tYXRyaXgoKSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAgI21vdGlmTV90YWJsZSA8LSBtb3RpZk1hdGNoZXMobW90aWZfaXgpICU+JSBhcy5tYXRyaXgoKSAgJT4lIGFzLmRhdGEuZnJhbWUoKSBhc190aWJibGUoKQojbW90aWZNX3RhYmxlICU+JSBkcGx5cjo6c2VsZWN0KDE6MykKI2NvbG5hbWVzKG1vdGlmTV90YWJsZSkgI2NvbG5hbWVzKG1vdGlmTWF0Y2hlcyhtb3RpZl9peCkpCm5jb2wobW90aWZNX3RhYmxlKSAjbmNvbChtb3RpZk1hdGNoZXMobW90aWZfaXgpKQptb3RpZk1fdGFibGVfcmFuZ2UgPC0gY2JpbmQoZmNfcmFuZ2VfY291bnRzZmlsLCBtb3RpZk1fdGFibGUpCm5jb2wobW90aWZNX3RhYmxlX3JhbmdlKQojbW90aWZNX3RhYmxlX3JhbmdlIDwtIGNiaW5kKGZjX3JhbmdlX2JpYXMgJT4lIGRwbHlyOjpzZWxlY3QocmFuZ2UpICxtb3RpZk1fdGFibGUpCgpwcmludCgiLS0tLSBzYXZlIG1vdGlmIC0tLS0iKQojLS0gc2F2ZSBtb3RpZiBpZCAtLS0tIwpmZmZpbGUgPC0gc3ViKCIuYmVkIiwiX21vdGlmSUQuY3N2IixwZWFrZmlsZSkKcHJpbnQoZmZmaWxlKQptb3RpZl9pZCAlPiUgcmVhZHI6OndyaXRlX2NzdihmZmZpbGUpCiMtLSBzYXZlIG1vdGlmIG1hdGNoIC0tLS0jCmZmZmlsZSA8LSBzdWIoIi5iZWQiLCJfbW90aWZNYXRjaGVzLmNzdiIscGVha2ZpbGUpCnByaW50KGZmZmlsZSkKbW90aWZNX3RhYmxlX3JhbmdlICU+JSByZWFkcjo6d3JpdGVfY3N2KGZmZmlsZSkKCgojPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSMKIy0tLS0tLSDopIfmlbDjga7mnaHku7bjgYzjgYLjgovmmYLjgavmnInnlKggLS0tLS0tIwpwcmludCgiPT09PT09PT09PSBkZXYgPT09PT09PT09PSIpCiMgc2xvdChkZXYsICJlbGVtZW50TWV0YWRhdGEiKSAjRGF0YUZyYW1lIHdpdGggMTI4IHJvd3MgYW5kIDMgY29sdW1ucwpkZXZfdGFibGUgPC0gc2xvdChkZXYsICJlbGVtZW50TWV0YWRhdGEiKSAlPiUgYXNfdGliYmxlKCkgICU+JSBkcGx5cjo6cmVuYW1lKG1vdGlmX25hbWU9bmFtZSkgI3JlbmFtZSBtb2RpZiAyMDIwMDYxNgpkZXZfdGFibGVfd2l0aGlkIDwtIGRldl90YWJsZSAlPiUgcmlnaHRfam9pbihtb3RpZl9pZCwuLCBieSA9ICJtb3RpZl9uYW1lIikgCiNkZXZfdGFibGVfd2l0aGlkIDwtIGRldl90YWJsZSAlPiUgcmlnaHRfam9pbihtb3RpZl9pZCwuLCBieSA9ICJuYW1lIikKCnByaW50KCItLSBkZXYgKGJpYXMtY29ycmVjdGVkIGRldmlhdGlvbnMpIC0tIikKZGV2X2RldmlhdGlvbnMgPC0gZGV2IEBhc3NheXMgQGRhdGEgQGxpc3REYXRhJGRldmlhdGlvbnMgJT4lIGFzX3RpYmJsZShyb3duYW1lcyA9ICJtb3RpZl9JRCIpCnByaW50KCItLSBkZXYgKHopIC0tIikKZGV2X3ogPC0gZGV2IEBhc3NheXMgQGRhdGEgQGxpc3REYXRhJHogJT4lIGFzX3RpYmJsZShyb3duYW1lcyA9ICJtb3RpZl9JRCIpCgpwcmludCgiLS0tLSBzYXZlIGRldmlhdGlvbnMgLS0tLSIpCiMtLSBzYXZlIGRldmlhdGlvbnMgLS0tLSMKZmZmaWxlIDwtIHN1YigiLmJlZCIsIl9kZXZpYXRpb25zLmNzdiIscGVha2ZpbGUpCnByaW50KGZmZmlsZSkKZGV2X2RldmlhdGlvbnMgJT4lIHJlYWRyOjp3cml0ZV9jc3YoZmZmaWxlKQojLS0gc2F2ZSBkZXYgKHopIC0tLS0jCmZmZmlsZSA8LSBzdWIoIi5iZWQiLCJfZGV2X3ouY3N2IixwZWFrZmlsZSkKcHJpbnQoZmZmaWxlKQpkZXZfeiAlPiUgcmVhZHI6OndyaXRlX2NzdihmZmZpbGUpCgojPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSMKCgoKYGBgCgoKCg==